【问题标题】:I'm trying to make an array of char arrays using malloc and then fill in the arrays using for [closed]我正在尝试使用 malloc 创建一个 char 数组数组,然后使用 for [关闭] 填充数组
【发布时间】:2014-02-27 09:14:39
【问题描述】:

我使用 malloc 创建了数组指针,并试图用文本文件中的字符串填充,但是当我运行程序时出现分段错误。

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

int main()
{
  char *filename = "textfile.txt";
  int rows = 10;

  FILE *fp;
  char* line = NULL;
  size_t length = 0;
  ssize_t read;


  //make a 10 line *char array 
  char **aPointer = (char**)malloc(sizeof(char*)*rows);
  if ((aPointer = NULL))
  {
    printf("Memory error\n");
    exit(1);
  }

  //open file
  if ((fp = fopen(filename, "r")) == NULL)
  {
    fprintf(stderr, "Error opening file");
    exit(1);
  }

//read line from file to array
  int i = 0;
  while(((read = getline(&line, &length, fp)) != -1) && (i<rows))
  {
    strcpy(aPointer[i], line);
    i++;
  }

  return 0;
}

-分段错误(核心转储)-

如何填写数组?

【问题讨论】:

  • 我怀疑显示的那些行是崩溃的直接原因(尽管它们可能是间接的)。有问题的请发short and complete program (a.k.a. a SSCCE)
  • 哦,学习如何使用调试器。如果你在调试器中运行你的程序,它将在崩溃的位置停止,你可以例如检查函数调用堆栈和变量的值。如果不出意外,请使用调试信息(gcc 的-g 标志)构建程序并在调试器中运行,然后将bt 命令的结果发布到the GNU debugger
  • 没有足够的信息来回答这个问题,请用实际发生崩溃的代码来完成。

标签: c arrays pointers char malloc


【解决方案1】:

这很可能是导致错误的原因:

strcpy(aPointer[i], line);

您实际上并未初始化aPointer[i],因此aPointer[i] 的值是不确定的。使用此值会导致未定义的行为,并且因为它被用作指针,很可能会导致崩溃。

一个快速的解决方案是在每次调用getline 之前将line 设置为NULL,因为该函数将分配行所需的空间,然后您可以分配

line = NULL;
while(i < rows && (read = getline(&line, &length, fp)) != -1)
{
    aPointer[i++] = line;
    line = NULL;
}

注意:我更改了while 的条件顺序,以使用&amp;&amp; 运算符的短路功能,如果您阅读了足够多的行,则不会读取一行。

完成后不要忘记free分配的内存。

【讨论】:

  • 我仍然遇到段错误。我也在尝试使用 gdb 进行调试,但这是我第一次使用 gdb,所以我不确定如何解释错误
  • @user238600 通过在 GCC 命令行中添加标志 -g 来构建调试信息。然后使用命令gdb ./my_program 在 GDB 中运行。在 GDB 命令提示符下使用run 命令实际运行程序。当它因错误而停止时,使用bt 命令显示函数调用堆栈“Back Trace”,复制bt 命令的输出并编辑您的问题以包含它。从那开始,我们可以继续为您提供帮助。
  • 程序收到信号SIGSEGV,分段错误。 0x00000000004007af in main () at sscce.c:44 44 aPointer[i++] = line; (gdb) bt #0 0x00000000004007af in main () at sscce.c:44 (gdb) bt
  • @user238600 此时,执行命令print iprint rows。这些命令将显示变量irows 的值。如果i 等于或大于rows,你忘了在循环中检查。
  • (gdb) print i $1 = 1 (gdb) print rows $2 = 20
【解决方案2】:

如果我没记错的话,你的代码如下:

int rows=3;

字符**aPointer = (char**)malloc(sizeof(char*)*rows);

aPointer[0] = "asdasdfasdfasdf";

aPointer[1] = "asdfsdf";

aPointer[2] = "line";

printf("\n aPointer0[%s],aPointer1[%s],aPointer1[%s]\n",aPointer[0],aPointer[1],aPointer[2]);

没有任何问题。

Output:

aPointer0[asdasdfasdfasdf],aPointer1[asdfsdf],aPointer1[line]

在上面的例子中,aPointer 只能有引用。 如果要复制到其中,可以使用strcpy() 例如strcpy(apointer[1],"myText");

【讨论】:

    【解决方案3】:

    您调用的 malloc 只是为指针分配内存,而不是为字符串本身。

    您可以对每个字符串执行 malloc 操作。然后使用 strcpy 复制字符串,它应该可以工作。

     aPointer[0] = malloc(sizeof(char) * the_string_size_you_want);
     strcpy(apointer[0],"asdasdfasdfasdf");
    

    【讨论】:

    • 如果指针仅用于只读访问,那很好。 (虽然在这种情况下 aPointer 应该被声明为 const。)
    • 仍然出现段错误,我第一次尝试使用 gdb 但我不确定如何解释错误:37 aPointer[0] = malloc(sizeof(char) * 10); (gdb) s __GI___libc_malloc (bytes=140737488346560) at malloc.c:2845 2845 malloc.c: 没有这样的文件或目录。 malloc.c 中的 (gdb) s 2850
    【解决方案4】:

    问题是您正在尝试使用指针数组**apointer,同时仅为每行的指针分配大小。

    试试这样的

    int sizeOfEachRow=50;  // This should be the maximum size of any line
    
    // Create an array of pointers. 
    // Note that individual element is still an uninitialize pointer
    char **aPointer = (char**)malloc(sizeof(char*)*rows);
    
      --snipped--
    
    while(((read = getline(&line, &length, fp)) != -1) && (i<rows))
      {
        // Assign memory to each pointer
        aPointer[i]=(char*)malloc(sizeof(char)*sizeOfEachRow);
        strcpy(aPointer[i], line);
        i++;
      }
    

    【讨论】:

      猜你喜欢
      • 2020-11-10
      • 2014-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多