0

我在unix中运行程序。它有分段错误。我发现它来自 read_names 函数中的 for 循环。当我禁用循环并设置 i = 0 时,它起作用了。但是,当我设置 i = 1 或其他数字时,它再次显示分段错误。我认为我存储字符串的方式可能是错误的。谁能帮我解决这个问题?

此外,我可以使用 strtok 将字符串保存到二维数组中吗?

谢谢你。

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

void alloc(char ***surname, char ***first, char **mid_init, int num);
void read_names(FILE *inp, char ***surname, char ***first, char **mid_init, int num );
void free_memory(char ***surname, char ***first, char **mid_init, int num);

int main(int argc, char *argv[])
{
  int num;
  char **surname, **first, *mid_init;
  FILE *inp = fopen(argv[1], "r");  
  FILE *outp = fopen(argv[2], "w");
  char array[79];

  fgets(array, 79, inp);
  fgets(array, 79, inp);
  fgets(array, 79, inp);
  printf("%s", array);

  fscanf(inp, "%d", &num);
  fprintf(outp, "%d \n\n", num+10);

  alloc(&surname, &first, &mid_init, num);
  read_names(inp, &surname, &first, &mid_init, num);
  free_memory(&surname, &first, &mid_init, num);



  fclose(inp);
  fclose(outp);

  return 0;
}

void alloc(char ***surname, char ***first, char **mid_init, int num)
{
  int i;

  *surname = (char**)malloc(num * sizeof(char*));
  *first = (char**)malloc(num * sizeof(char*));
  *mid_init = (char*)malloc(num * sizeof(char));

  for(i=0; i<num; i++)
  {
    (*surname)[i] = (char*)malloc(15*sizeof(char));
    (*first)[i] = (char*)malloc(10*sizeof(char));
  }
}

void read_names(FILE *inp, char ***surname, char ***first, char **mid_init, int num )
{
  char *token, array[79];
  char delim[6] = ", .\n";
  int i=0/*, k=0*/;

  printf("loop begins\n");

  for(i=0; i<num; i++)
  {
      fgets(array, 79, inp);
      printf("%s\n", array);

      fgets(array, 79, inp);
      printf("%s\n", array);

      token = strtok(array, delim);
      strcpy( *(*(surname+i)+0), token);
      printf("%s   ", *(*(surname+i)+0));

      token = strtok(NULL, delim);  
      strcpy( *(*(first+i)+0), token);
      printf("%s  ", *(*(first+i)+0));

      token = strtok(NULL, delim);
      **mid_init = token[0];
      printf("%s\n", *mid_init);


  }
     printf("\nloop ends\n");
}

void free_memory(char ***surname, char ***first, char **mid_init, int num)
{
  int i;

  free((*mid_init));

  for(i=0;i<num;i++)
  {
    free((*surname)[i]);
    free((*first)[i]);
  }
}
4

2 回答 2

2

您的读取功能应定义为:

void read_names(..., char **surname, char **first, ...)

您将***surname指针传递给alloc()函数,因为您正在更改外部变量surname。读取函数不这样做,它访问内存。

然后替换这个可怕的:)代码:

strcpy( *(*(first+i)+0), token);

strcpy(*(first+i), token);

更具可读性(如alk所建议的)

strcpy(first[i], token);

实际上,为了便于阅读,我建议使用char *pointer[];声明。

您用于strtok将字符串分隔为标记。使用 strcpy withstrtok填充您的二维数组。

此外,您还有内存泄漏。

您需要添加free_memory()功能

free(*surname);

但可以通过更改 free_function 定义来简化

void free_memory(char **surname, ..., int num)
{
  ...
  for(i=0;i<num;i++)
  {
    free(surname[i]);
    ...
  }
  free(surname);
}
于 2013-11-12T06:56:59.827 回答
0

首先,代码错过了所有相关系统调用的错误检查:

  • fopen()
  • fgets()
  • fscanf()
  • malloc()

也不要malloc/calloc/realloc像在 C 中那样强制转换结果,这不是必需的或不推荐的。


现在主要问题:

改变

strcpy( *(*(surname+i)+0), token);

成为

strcpy((*surname)[i]), token);

使用方式相同first


这条线

**mid_init = token[0];

没有意义,因为您保存了指向分配给函数的本地内存的指针,该函数离开后立即无效。


free_memory()添加

free(*surname);
free(*first);

在循环之后避免内存泄漏。

于 2013-11-12T07:13:46.337 回答