重新分配一个指针数组什么都不做
realloc an array of pointers is doing nothing
我有一个字符串数组,当它不再有 NULL 指针(意味着数组已满)时,我想扩展它。
我试过 realloc 但没有成功,我想我没有正确思考指针。
这是我的代码:
int storage; //global, outside of main
int i, key;
char **people;
char **phones;
printf("Please enter a storage cacpity:\n");
scanf("%d",&storage);
printf("\n");
people=malloc(storage*sizeof(char *));
phones=malloc(storage*sizeof(char *));
for (i=0; i<storage; i++) {
people[i] = NULL;
phones[i] = NULL;
}
void AddNewContact(char * people[], char * phones[]) {
char name[100];
char phone[12];
int i, listfull = 0;
printf("Enter a contact name:\n");
scanf("%s",&name);
printf("Enter a phone number:\n");
scanf("%s",&phone);
for (i=0; i<storage; i++) {
if (people[i]==NULL) {
people[i] = (char *)malloc(strlen(name));
phones[i] = (char *)malloc(strlen(phone));
strcpy(people[i],name);
strcpy(phones[i],phone);
break;
}
listfull = 1;
}
if (listfull == 1) {
storage++;
people = realloc(&people,(storage)*sizeof(char *));
phones = realloc(&phones,(storage)*sizeof(char *));
people[storage-1] = NULL;
phones[storage-1] = NULL;
strcpy(people[storage-1],name);
printf("\nData Base extanded to %d",storage);
}
printf("\n");
return;
}
void PrintAll(char * people[], char * phones[]) {
int i;
for (i=0; i<storage; i++) {
if (NULL != people[i]) {
printf("Name: %s, ",people[i]);
printf("Number: %s\n",phones[i]);
}
}
printf("\n");
return;
}
任何帮助将不胜感激,我坚持了几个小时并且没有解决这个问题。
你有4个重要的错误,首先你将数组的地址传递给scanf()
那是错误的,你应该改变
scanf("%s", &name);
到
scanf("%s", name);
以及 scanf("%s",&phone);
,我还应该建议使用长度说明符 scanf
来防止缓冲区溢出,例如
scanf("%99s", name);
即name
数组的长度 -1,为 '[=24=]'
终止符。
其次,你的realloc
调用也是错误的,你应该传递指针而不是它的地址,而不是这个
people = realloc(&people,(storage)*sizeof(char *));
你应该这样做
people = realloc(people, storage * sizeof(char *));
但即使这样也不是 100% 正确,因为万一 realloc
失败,您将覆盖指针,然后您将没有机会清理内存,所以您实际上应该做一些事情 [= =30=]
void *pointer;
pointer = realloc(people, storage * sizeof(char *));
if (pointer == NULL)
free_people_andCleanUpOtherResourcesAndExitFromThisFunction();
people = pointer;
phones
也是如此。
第三,你应该总是为一个额外的字符分配 space,终止 '[=24=]'
,this
people[i] = (char *)malloc(strlen(name));
应该阅读
people[i] = malloc(1 + strlen(name));
请注意,我删除了不必要的强制转换。
第四,你在第一次迭代中跳出循环,离开 listfull == 1
,即使列表还未满。
for (i=0; i<storage; i++) {
if (people[i]==NULL) {
people[i] = malloc(1 + strlen(name));
phones[i] = malloc(1 + strlen(phone));
strcpy(people[i],name);
strcpy(phones[i],phone);
break;
}
listfull = 1;
}
我会在循环之外推荐这个
listfull = (i == storage);
注意:函数失败的可能性有多大并不重要,如果理论上会失败,您应该始终检查它是否失败,这将节省您数小时的调试时间发现一个非常愚蠢的错误,你没有检查可能的失败。
你有
listfull = 1;
在你的 (for i ...)
循环内,它应该在循环外,像这样
if (i == storage) // if loop completed
listfull = 1;
接下来,您的部分程序评论说某些变量是全局声明的,但它们后面是可执行代码语句,必须在函数内,"global" 变量实际上是局部的?
我有一个字符串数组,当它不再有 NULL 指针(意味着数组已满)时,我想扩展它。 我试过 realloc 但没有成功,我想我没有正确思考指针。
这是我的代码:
int storage; //global, outside of main
int i, key;
char **people;
char **phones;
printf("Please enter a storage cacpity:\n");
scanf("%d",&storage);
printf("\n");
people=malloc(storage*sizeof(char *));
phones=malloc(storage*sizeof(char *));
for (i=0; i<storage; i++) {
people[i] = NULL;
phones[i] = NULL;
}
void AddNewContact(char * people[], char * phones[]) {
char name[100];
char phone[12];
int i, listfull = 0;
printf("Enter a contact name:\n");
scanf("%s",&name);
printf("Enter a phone number:\n");
scanf("%s",&phone);
for (i=0; i<storage; i++) {
if (people[i]==NULL) {
people[i] = (char *)malloc(strlen(name));
phones[i] = (char *)malloc(strlen(phone));
strcpy(people[i],name);
strcpy(phones[i],phone);
break;
}
listfull = 1;
}
if (listfull == 1) {
storage++;
people = realloc(&people,(storage)*sizeof(char *));
phones = realloc(&phones,(storage)*sizeof(char *));
people[storage-1] = NULL;
phones[storage-1] = NULL;
strcpy(people[storage-1],name);
printf("\nData Base extanded to %d",storage);
}
printf("\n");
return;
}
void PrintAll(char * people[], char * phones[]) {
int i;
for (i=0; i<storage; i++) {
if (NULL != people[i]) {
printf("Name: %s, ",people[i]);
printf("Number: %s\n",phones[i]);
}
}
printf("\n");
return;
}
任何帮助将不胜感激,我坚持了几个小时并且没有解决这个问题。
你有4个重要的错误,首先你将数组的地址传递给scanf()
那是错误的,你应该改变
scanf("%s", &name);
到
scanf("%s", name);
以及 scanf("%s",&phone);
,我还应该建议使用长度说明符 scanf
来防止缓冲区溢出,例如
scanf("%99s", name);
即name
数组的长度 -1,为 '[=24=]'
终止符。
其次,你的realloc
调用也是错误的,你应该传递指针而不是它的地址,而不是这个
people = realloc(&people,(storage)*sizeof(char *));
你应该这样做
people = realloc(people, storage * sizeof(char *));
但即使这样也不是 100% 正确,因为万一 realloc
失败,您将覆盖指针,然后您将没有机会清理内存,所以您实际上应该做一些事情 [= =30=]
void *pointer;
pointer = realloc(people, storage * sizeof(char *));
if (pointer == NULL)
free_people_andCleanUpOtherResourcesAndExitFromThisFunction();
people = pointer;
phones
也是如此。
第三,你应该总是为一个额外的字符分配 space,终止 '[=24=]'
,this
people[i] = (char *)malloc(strlen(name));
应该阅读
people[i] = malloc(1 + strlen(name));
请注意,我删除了不必要的强制转换。
第四,你在第一次迭代中跳出循环,离开 listfull == 1
,即使列表还未满。
for (i=0; i<storage; i++) {
if (people[i]==NULL) {
people[i] = malloc(1 + strlen(name));
phones[i] = malloc(1 + strlen(phone));
strcpy(people[i],name);
strcpy(phones[i],phone);
break;
}
listfull = 1;
}
我会在循环之外推荐这个
listfull = (i == storage);
注意:函数失败的可能性有多大并不重要,如果理论上会失败,您应该始终检查它是否失败,这将节省您数小时的调试时间发现一个非常愚蠢的错误,你没有检查可能的失败。
你有
listfull = 1;
在你的 (for i ...)
循环内,它应该在循环外,像这样
if (i == storage) // if loop completed
listfull = 1;
接下来,您的部分程序评论说某些变量是全局声明的,但它们后面是可执行代码语句,必须在函数内,"global" 变量实际上是局部的?