观看视频 - https://youtu.be/kXXpj1ruE0o
好吧,我正在编写这个程序,它会打印最后 n 行输入。 n 是命令行参数,默认为 10。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char line[500];
int pos = 0;
void copy(char* tailed[], int n){
if(pos == n){
// moving contents of array to one position back
for(int i=0; i<pos-1; i++)
tailed[i] = tailed[i+1];
//free(tailed[pos-1]); not working
pos--;
}
tailed[pos++] = strcpy(malloc(strlen(line) * sizeof(char)), line);
}
int main(int argc, char* argv[]){
if(argc > 2){
printf("[*]Error");
return 0;
}
int n = argc==2 ? atoi(argv[1]) : 10, c;
char* tailed[n];
while(scanf("%[^\n]%*c", line) != EOF){
copy(tailed, n);
}
for(int i=0; i<pos; i++)
printf("%s\n", tailed[i]);
}
此代码工作正常并打印最后 n 行。但是当我使用 free(tailed[pos-1]) 时,程序给出了错误的答案。
代码解释..
scanf() 接受输入并将其存储在字符数组行中。如果 pos 小于 n,则该行将复制到 malloc 创建的新内存,并将指针存储在尾数组中。
如果 pos 变量大于 n,则数组的内容将向后移动一个位置,并使用 free() 清除最后一个元素。
如果我不使用 free(),程序会给出正确的输出,但在使用时却不会。
最佳答案
至少您可能会调用 undefined behavior 通过创建一个太短的缓冲区来接受随后写入的内容。
行:
tailed[pos++] = strcpy(malloc(strlen(line) * sizeof(char)), line);
除了非常非常规之外,还将目标缓冲区缩短 1,并且应该是:
tailed[pos++] = strcpy(malloc(strlen(line) * sizeof(char))+1, line);
^^
strlen(...) 返回当前占用缓冲区的字符计数,但不包括\0 字符。如果要为新缓冲区分配内存,该缓冲区需要足够大以包含相同大小的字符串,则需要在 malloc 语句中包含 +1 大小以允许 NULL 终止。永远。
举例来说,当我在我的系统上运行您的原始代码时,我得到以下运行时指示:
一旦我添加了+1
,它就可以正常工作,没有任何运行时错误。
顺便说一句,输入 list of good C debuggers Google 得到了相当不错的结果...
关于c - 如何调试这段c代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42935539/