#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编译器上执行此程序时,我得到分段错误。我不明白为什么会这样?你能告诉我这个错误在哪里吗?
答案 0 :(得分:1)
p
中的 main
按值移交给add
。 add
然后修改本地副本,但不修改原始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
}
。你自己并没有真正做过缓冲区复制恕我直言。