1

我复制了一些代码,这些代码只是将文件读取到字符串并从旧程序打印字符串。它工作正常,所以我决定对其进行一些修改。新程序是

#include <stdio.h>
#include <string.h>

int main() {
    FILE *itemlist = fopen("itemlist", "r");
    char *currentstring, charbuffer[2];
    // char itemstart = 0;
    while (fgets(charbuffer, 2, itemlist)) {
        strcat(currentstring, charbuffer);
    }
    printf("%s", currentstring);
    return 0; 
}

它按预期工作。但是当我取消注释该itemstart行时,它会出现分段错误。我什至没有使用它,就我而言,将 char 初始化为 0 并不违法。我认为这是类型的问题,然后我将其更改为 short ,然后更改为 int ,它仍然给出段错误。

但后来我删除了这= 0部分,它又开始工作了。然后我决定把它放回去,用 gdb 调试二进制文件,段错误在strcat.

这怎么可能?

4

4 回答 4

4

currentstring是一个悬空指针,因此strcat(currentstring, charbuffer);会导致未定义的行为。

可能取消注释char itemstart = 0会初始化一些内存0并且访问冲突是可见的,但这只是一个猜测。未定义的行为意味着任何事情都可能发生。

您应该为以下内容分配内存currentstring

currentstring = malloc(10); //or whatever length you need
于 2012-04-13T20:14:15.180 回答
1

您必须为变量分配空间currentstring并控制其大小以避免段错误/堆损坏。

#define MAX_BUFFER_SIZE 32
//...
FILE *itemlist = fopen("itemlist", "r");
char *currentstring = malloc(MAX_BUFFER_SIZE+1);
char *tmpbuf;
char charbuffer[2];
// char itemstart = 0;
int bytesloaded = 0;
while (fgets(charbuffer, 2, itemlist)) {

    if(bytesloaded + 2 > buf_size) {
       /* call realloc() */
        buf_size += MAX_BUFFER_SIZE;
        tmpbuf = realloc(currentstring, buf_size);
        if(tmpbuf == NULL) { /* Get off loop. Using break or return. */
             break; 
        } 
        currentstrig = tmpbuf;
     }
    memcpy(currentstring + bytesloaded, charbuffer, 2);
    bytesloaded += 2;
}
//... 
free(currentstring);

我没有测试过,但我相信它有效。

于 2012-04-13T20:36:16.917 回答
1

C 语言的不安全性使得取消注释不相关行时的段错误成为可能。错误程序的最终行为是由编译器做出的细微选择决定的。

当面对这样的疯狂时,你应该首先尝试更正你的代码。当然,这并不总是那么容易。在一个 8 行的程序上,你应该没问题。

于 2012-04-13T20:17:06.273 回答
1

您需要为 currentstring 分配一些空间。

于 2012-04-13T20:13:51.200 回答