【问题标题】:strcpy char pointer abort [closed]strcpy char指针中止[关闭]
【发布时间】:2013-01-24 19:02:50
【问题描述】:

我有这个代码:

     char **arr;
     char* line=NULL;
     int i=0;
     size_t len=0;
     ssize_t read1;

     fp=fopen("list.txt","r");
     if(fp==NULL)
         exit(EXIT_FAILURE);

     while((read1=getline(&line,&len,fp))!=-1)
         i++;
     fclose(fp);

     fp=fopen("list.txt","r");
     if(fp==NULL)
         exit(EXIT_FAILURE);

     arr=(char**)malloc(i*sizeof(char*)); // i is a variable i use to know the number of lines
     i=0;

     while((read1=getline(&line,&len,fp))!=-1)
     {
         line[strlen(line)]='\0';
         arr[i]=(char*)malloc(strlen(line)+1);
         strcpy(arr[i],line);
         i++;
     }

当我尝试strcpy 时程序崩溃。是malloc 问题吗? 我很确定i 足够大。 line 最初是 char* 和 NULL。

编辑:我忘了这个程序是在 Qt 中的。

【问题讨论】:

  • 你不需要在 C 程序中强制转换 malloc() 的返回值。
  • "i 是我用来知道行数的变量" - 那为什么它被命名为i 而不是@ 987654331@/linesNumber?
  • 你怎么知道开头的i足够大?
  • line[strlen(line)]='\0' 没有任何意义。
  • @Emil:由于您将line 定义为NULL,这意味着您希望getline 为您分配缓冲区。所以有几件事。 1)你不需要strcpy那么,你可以只存储指针,它是你来管理的。 2) 完成后需要将 line 设置为 NULL,否则 next 调用将重用该缓冲区,如果它是较长的行,可能会太短并溢出!

标签: c++ qt malloc strcpy


【解决方案1】:

代码有几个问题,我会用我认为应该可行的方式发表评论...:

 // I **assume** that these are the definitions for these variables 
 // based on your comments
 size_t len = 0;
 char *line = NULL;
 ssize_t read1;

 // I **assume** that i has a reasonable value here, but this is not good to assume, 
 // what if the file is a line longer tomorrow? I hope that you calculate the number 
 // of lines somehow, that would be "less bad"
 int i = 10; // 10 lines in the file, who knows ?!?
 char **arr;

 // don't bother casting...
 arr = malloc(i * sizeof(char*)); 
 i=0;

 while((read1 = getline(&line, &len, fp)) != -1) {

     // THIS LINE DOES NOTHING, so we can just remove it
     // line[strlen(line)]='\0';

     arr[i] = line; // since you asked getline to allocate a buffer for 
                    // you (line was NULL), you can just store the buffer directly
                    // it's YOURS
     i++;

     // THIS IS THE BIG ONE:
     // it is needed because otherwise the NEXT call to getline will 
     // reuse the same buffer, which may not be big enough
     line = NULL;
 }

此外,稍后进行清理时,您应该执行以下操作:

int j;
for(j = 0; j < i; ++j) {
    free(arr[j]);
}
free(arr);
arr = NULL; // not necessary, but good practice to avoid double frees and such

【讨论】:

  • 谢谢您,但仍然无法正常工作。我将编辑代码以使其更清晰。
  • +1: @EmilGrigore 请这样做,因为如果 getline() 执行此规定的操作,则此代码是正确的(除了 i 的缺失检查,这很容易成为最差的命名变量在这个代码块中。
  • @Emil,请定义“不起作用”,因为据我所知,我提供的代码不应该崩溃。您是否尝试过在我的代码中添加“reNULLing”行?
  • @Evan Teran 是的,我试过了,但它仍然崩溃。
  • @Emil:: 另外,根据您的编辑,您需要在第二个循环(实际读取行的循环)之前将line 设置为NULL。因为之前的计数循环将line 设置为非NULL 值。
【解决方案2】:

你不测试你是否比原来的 i 有更多的行

 arr=(char**)malloc(i_ori*sizeof(char*));//i_ori is a variable i use to know the number of lines
 i=0;

 while((read1=getline(&line,&len,fp))!=-1 && i<i_ori)

此外,您永远不会测试 malloc 是否返回 NULL !见https://stackoverflow.com/a/2280342/1458030

@Emil Grigore:当我尝试 strcpy 时,程序崩溃。是 malloc 问题?我很确定我足够大。

是的!您需要测试 NULL。

如果您使用 C++ 和 Qt,为什么不使用容器、流?

【讨论】:

  • 我确定我的行数和我一样
  • @EmilGrigore:那么请编辑您的帖子,添加一个 minimal test-case 来证明这一点。
猜你喜欢
  • 2017-03-30
  • 2021-08-11
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 2019-02-13
  • 2011-08-04
相关资源
最近更新 更多