此代码段中双指针和三指针的重要性

时间:2014-12-03 12:18:24

标签: c dynamic-memory-allocation realloc

#include<stdio.h>
#include<stdlib.h>
void add(char **p);
void print(char **p);
int cnt=0;
main()
{
  int option;
  char **p=NULL;
while(1)
{
  printf("------MENU-----\n");
  printf("1>input\n 2>print\n3>exit\n");
  printf("enter ur choice\n");
  scanf("%d",&option);getchar();
 switch(option)
 {
    case 1: add(p);
            break;
    case 2: print(p);
            break;
   case 3: return;
   default: printf("Invalid option\n");

 }
}
}
void add(char **p)
{
  int i;
  p=(char**)realloc(p,(cnt+1)*sizeof(char*));
  if(p==NULL)
  {
        printf("Error: memory not available\n");
        return;

  }
  p[cnt]=NULL;
  p[cnt]=(char*)realloc(p[cnt],20*sizeof(char));

  puts("enter a name");
  gets(p[cnt]);
  cnt++;
  printf("cnt=%d\n",cnt);
}
void print(char **p)
{
  int i;
  for(i=0;i<cnt;i++)
  printf("p[%d]=%s\n",i,p[i]);
}

在上面的代码中,我正在创建一个名称数据库。为此,我使用动态内存分配。我是使用指针数组方法为2D数组分配内存。当我在 gcc编译器上执行此程序时,我得到分段错误。我不明白为什么会这样?你能告诉我这个错误在哪里吗?

5 个答案:

答案 0 :(得分:1)

p中的

main按值移交给addadd然后修改本地副本,但不修改原始p

除了可怕的格式以及指向main p add ... case 1: add(&p); ... void add(char ***p) { int i; *p = realloc(*p,(cnt+1)*sizeof(char*)); if(*p==NULL) { printf("Error: memory not available\n"); return; } (*p)[cnt]=NULL; (*p)[cnt]=realloc((*p)[cnt],20*sizeof(char)); puts("enter a name"); gets((*p)[cnt]); cnt++; printf("cnt=%d\n",cnt); } 的指针所需的一切:

{{1}}

答案 1 :(得分:1)

在main中,您所做的只是分配p = NULL,然后在print中使用此NULL指针,这会导致段错误。请注意,add(p)相当于add(NULL),并且不会更改p。 您的意思是使用add(&p)传递地址吗?如果是这样,你需要用*

的数字来调整一下

答案 2 :(得分:0)

通过参考传递。您需要传递指针的地址,以确保函数add()中的更改反映在main()中。避免使用gets()

在这种情况下

add(&p);

因此,您的add()函数定义应更改为处理此问题。 或者另一种方法是使add函数进行所需的分配并将该地址返回给指针

char **add();

检查以下代码:

char  **add(char **p)
{
  int i;
  p=(char**)realloc(p,(cnt+1)*sizeof(char*));
  if(p==NULL)
  {
        printf("Error: memory not available\n");
        return;

  }
  p[cnt]=NULL;
  p[cnt]=(char*)realloc(p[cnt],20*sizeof(char));

  scanf("%s",p[cnt]);
  cnt++;
  printf("cnt=%d\n",cnt);
  return p;
}

所以你的电话应该是:

p = add(p);

答案 3 :(得分:0)

在add函数中创建了2D指针p的副本,更新此指针不会反映在main函数中。 这个问题的一个快速解决方案是返回2D指针&#39; p&#39;来自添加功能。

char** print(char **p)
{
    ....
    ....
    return p;
}

答案 4 :(得分:0)

除了其他事情,我不认为有人提到重新分配失败的realloc陷阱。假设这个电话

p=(char**)realloc(p,(cnt+1)*sizeof(char*));

无法分配新内存:接下来会发生什么?是的,您将获得NULL返回:但 分配的内存以及p指向的内存获取{{1 }}&#39; d。即时内存泄漏。

必须这样调用free

realloc

另一个原因使用char* pTemp = realloc(p, cnt + 1); if(pTemp != NULL) { p = pTemp; // Now safe to update p } else { // Error handling as required, possibly including freeing p } 。你自己并没有真正做过缓冲区复制恕我直言。