C_Debug


这篇博客记录我为 C/C++ 写过的bug

  • 源代码:
int check(List L1, List L2)
{
    ...
}
while ((ret=check(L1,L2)) = NULL) 
{
    ...
}

报错:

expression must be a modifiable lvalue

  • 分析:

这里lvalue 应该是 left value的意思。编译器说您表达式的左值必须是可变的。

发现问题是 == 写成了 =。左边因为存在括号,会先计算出括号内的值。也就是说,
(ret = check(L1,L2)) 将会被替换为check(L1,L2)的结果,在此处是一个指针类型的变量。一个普通变量的值不能被更改。(就像我不能写1 = 2;这样的语句。)

  • 修改方法:
    while ((ret=check(L1,L2)) == NULL)
    {
        ...
    }

  • 源代码
    char *str[10];
    str[1] = "Hello";
    编译器Warning:

    ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

char *str[10];定义的是指针数组。因此类似的,

char *p;
p = "Hello";

会报出同样的错误。

  • 分析:

"Hello"在C语言中是字符串常量,在c++中叫做string literal,类型是const char *其实际是一个指向首字母'H'地址的指针。

此处是将一个Const char *类型强制转换为 char *类型,有改动常量的可能性。

编译运行的结果会因编译器和操作系统共同决定,有的编译器会通过,有的会抛异常,就算过了也可能因为操作系统的敏感性而被杀掉。

  • 修改方法
    const char *p = "Hello";
    或者
    char *p = (char *) "Hello";

  • 问题

向一个字符指针读入字符串时出现segment fault。 例如: scanf("%s",p);

更隐蔽的情况是,我定义了一个字符指针数组。

char * str[10];
for (int i=0;i<10;i++)
{
    scanf("%s",str[i]);
}

  • 原因

在str数组中的每一个指针都是悬垂指针,没有指向一个已经分配的地址。

就像是我定义一个 char * p; 此时p指向的是NULL或者一个随机地址。

此时scanf("%s",p); 是会出问题的。

  • 修改方法
    for (int i=0;i<10;i++)
    {
        str[i]=(char)malloc(MAX_LEN * sizeof(char));
        scanf("%s",str[i]);
    }

C语言: variably modified 'xxx' at file scope

const int MAXLEN = 50;
char str[MAXLEN];

gcc编译报错。

  • 原因

C语言中的const并不是常量的意思。它的本意是只读 read only

The const qualifier really means read-only; an object so qualified is a run-time object which cannot (normally) be assigned to. The value of a const-qualified object is therefore not a constant expression in the full sense of the term, and cannot be used for array dimensions, case labels, and the like. (C is unlike C++ in this regard.) When you need a true compile-time constant, use a preprocessor #define (or perhaps an enum)

  • 解决方法:使用define

int a[3][4], (*num)[4]; num[0]=&a[1][3];
编译器报错: expression must be a modifiable Ivalue

  • 原因

int (*p)[4]; 指的是一个指针, 指向4个int类型数据

所以p = &a[0] 就是正确的。

(TYPE) malloc(SIZE);

  • 用法: 在动态内存(堆)中开辟 SIZE 字节的空间,返回首地址

  • 注意: TYPE 一般是一个指针,指针变量存储一个8字节整数。
    SIZE我们一般使用N*sizeof(TYPE),注意这里TYPE一不用指针,而是本体代表的数据类型。

非静态成员引用必须与特定对象相对

非静态成员引用必须与特定对象相对-CSDN博客


Author: Tsum
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Tsum !
  TOC