我是C的新手,所以我很难搞清楚这一点。我一次读取文件500个字节,计算文件中的行数,然后一旦我达到500行,我将其写入另一个文件。该文件根本没有正确出现,我认为这与我尝试连接长字符串然后将其写入文件有关。这是我现在的代码的主循环:
while (lineCount != 500)
{
if (lineCount == 500)
break;
readbytes = read(infd, buf, 500);
for (str = buf; *str; ++str)
{
lineCount += *str == '\n';
char *newPtr = realloc(forkBuf, (strlen(forkBuf) + strlen(str) + 2));
forkBuf = newPtr;
char* newFork = realloc(forkBuf, (strlen(forkBuf) + strlen(str) + 2));
sprintf(forkBuf, "%s%s", newFork, str);
if (lineCount == 500)
break;
}
if (lineCount < 500)
{
if(readbytes < 500){
write(outfd, forkBuf, (strlen(forkBuf) + 2));
break;
}
continue;
}
write(outfd, forkBuf, (strlen(forkBuf) + 2));
}
答案 0 :(得分:2)
您有两行代码:
char* newFork = realloc(forkBuf, (strlen(forkBuf) + strlen(str) + 2));
sprintf(forkBuf, "%s%s", newFork, str);
这会导致未定义的行为;如果realloc
重新分配到新地址,则forkBuf
指向释放的内存;即使realloc
有效,according to the standard:
此示例中的原始指针
ptr
[forkBuf
]无效,对它的任何访问都是未定义的行为(即使重新分配就位)。
我还要补充说,如果(可能会发生)forkBuf
等于newFork
,使用sprintf
将字符串复制到自身也是未定义的行为。
此外,这里有一个for
循环,其中str
基本上被视为单个字符。我重写整个循环,但快速破解可能是:
// One byte extra for the `\0`, and one for the new character
char *newPtr = realloc(forkBuf, (strlen(forkBuf) + 2));
if (newPtr == NULL)
panic(); // Or whatever error handling you might want
forkBuf = newPtr;
size_t len = strlen(forkBuf);
forkBuf[len] = *str;
forkBuf[len + 1] = '\0';
请注意,循环中只需要一个realloc()
,或者更好,循环外只有一个realloc(forkBuf, (strlen(forkBuf) + strlen(str) + 2));
。