由于某种原因,当我重新分配数组以将项目追加到数组时,它在段错误之前只能工作两次。当我尝试在数组内部打印字符串时,将发生段错误。我目前有一个NULL
终止的数组。
void apparr(char** arr, char* line) {
int length = 0;
// find the length of the array
while(arr[length] != NULL) {
length++;
}
// realloc with 2 extra spaces (1 for line, 1 for NULL)
arr = realloc(arr, sizeof(char*) * (length+2));
// set last element (which was NULL) to line
arr[length] = line;
// set the NULL terminator
arr[length+1] = NULL;
}
我不知道我可能在哪里出错,我唯一的猜测就是如何调用realloc。但是,我会理解这不适用于1个调整大小,但是我不知道为什么当我打印回阵列时,此方法适用于两个调整大小,然后是段错误。
它如何在main中使用:
int main(int argc, char** argv){
char** hist = malloc(sizeof(char**));
char* linep1;
char* linep2;
char* linep3;
char* linep4;
linep1 = (char*)malloc(strlen("test")*sizeof(char));
linep2 = (char*)malloc(strlen("test2")*sizeof(char));
linep3 = (char*)malloc(strlen("test3")*sizeof(char));
linep4 = (char*)malloc(strlen("test4")*sizeof(char));
strcpy(linep1, "test");
strcpy(linep2, "test2");
strcpy(linep3, "test3");
strcpy(linep4, "test4");
apphist(hist, linep1);
apphist(hist, linep2);
//apphist(hist, linep3); //uncommenting this line causes nothing to be printed
//apphist(hist, linep4); //uncommenting this line causes only test4 to be printed
int x = 0;
while (hist[x] != NULL) {
printf("%s\n", hist[x]);
x++;
}
}
答案 0 :(得分:2)
在主要功能中,您需要在功能hist
中检查NULL
的第一个元素为apphist
char** hist = malloc(sizeof(char*));
*hist = NULL;
函数apphist
仅在本地更改arr
的值。为了反映主要功能的变化,您需要将指针传递到arr
,即3D指针char ***arr
您应始终检查realloc
的结果并在失败时执行操作。
该功能的代码如下。
void apparr(char*** arr2, char* line) {
int length = 0;
char **arr = *arr2;
while(arr[length] != NULL) {
length++;
}
arr = realloc(arr, sizeof(char*) * (length+2));
if (arr == NULL) {
exit(1); // handle error
}
*arr2 = arr;
arr[length] = line;
arr[length+1] = NULL;
}
char** apparr(char** arr, char* line) {
int length = 0;
char **temp;
while(arr[length] != NULL) {
length++;
}
temp = realloc(arr, sizeof(char*) * (length+2));
if (temp == NULL) {
exit(1); // handle error
}
arr = temp;
arr[length] = line;
arr[length+1] = NULL;
return (arr);
}
//in main
hist = apphist(hist, linep1);
hist = apphist(hist, linep2);
答案 1 :(得分:0)
我认为您应先取消引用arr,然后再用于realloc。另一个观察; sizeof(char *)通常在32位体系结构中为4,在64位体系中为8,而不是1。
答案 2 :(得分:0)
对于一般情况,我认为您只需要调用长度为+1的realloc
arr = realloc(arr, sizeof(char*) * (length+1));
这是因为从先前状态开始,您已经有空间用于NULL终止指针。使用代码,您正在提议发生的事情是这样的
//重新分配之前的状态
字符串字符串为空
// apparr()调用
字符串字符串NULL未定义未定义//重新分配
String String String undefined undefined // arr [length] = line;
String String String NULL未定义// // arr [length + 1] = NULL;
第一次运行(末尾悬空分配的节点),但是第二次由于额外的分配,它可能以多种方式崩溃。
答案 3 :(得分:0)
您的代码中有几个错误:
这是您的主要错误。您不会替换给定指针中的值。使用指向该指针的指针是正确的,但是您需要取消引用它。为此,您需要将指针传递到hist
并在重新分配时取消引用:
*arr = realloc(*arr, sizeof(char*) * (length + 2));
指针列表未初始化,在第一次分配后,您需要设置第一个指针:
hist[0] = NULL;
您的测试字符串分配为1:
linep1 = malloc((strlen("test") + 1) * sizeof(char));
linep2 = malloc((strlen("test2") + 1) * sizeof(char));
linep3 = malloc((strlen("test3") + 1) * sizeof(char));
linep4 = malloc((strlen("test4") + 1) * sizeof(char));
其他说明:
apparr()
是错误的,您在apphist()
中叫main()
。argc
和argv
,所以写int main(void)
char** hist = malloc(sizeof(char*));
malloc()
返回了指向void
的指针,因此无需强制转换。可以来回分配指向void
的指针和其他指针,而无需强制转换。malloc()
/ strcpy()
对替换为strdup()
。apphist()
那样用字符串作为“立即”值调用apphist(hist, "test");
main()
应该返回一个int
,EXIT_SUCCESS
是正确的值。const
,以使事情更安全。但是想想什么是常数。答案 4 :(得分:0)
其他人已经提到了所有错误和可能的陷阱。
在下面找到一个附加元素到数组函数的更通用的实现:
#include <stdlib.h>
#include <errno.h> /* for EINVAL */
int apparr(char *** parr, char * line) {
size_t length = 0;
if (NULL == *parr) {
if (NULL != line) {
errno = EINVAL;
return -1;
}
} else {
// find the length of the array
while (NULL != (*parr)[length]) {
++length;
}
}
{
// realloc with 2 extra spaces (1 for line, 1 for NULL)
void * pv = realloc(*parr, (length+1) * sizeof **parr);
if (NULL == pv) {
return -1; /* By convention -1 indicates failure. */
}
*parr = pv;
}
(*parr)[length] = line;
if (0 < length) {
(*parr)[length + 1] = NULL;
}
return 0; /* By convention 0 indicates success. */
}
并像这样使用它:
#include <stdlib.h>
#include <stdio.h>
int apparr(char *** parr, char * line) {
int main(int argc, char** argv) {
char ** hist = NULL;
char * linep1;
char * linep2;
char * linep3;
char * linep4;
if (-1 == apparr(&hist, NULL)) {
perror("apphist() failed initially\n");
exit(EXIT_FAILURE);
}
linep1 = malloc(strlen("test") + 1);
linep2 = malloc(strlen("test2") + 1); /* +1 for the c-string's 0-termination; sizeof (char) is 1 by definition */
linep3 = malloc(strlen("test3") + 1);
linep4 = malloc(strlen("test4") + 1);
strcpy(linep1, "test");
strcpy(linep2, "test2");
strcpy(linep3, "test3");
strcpy(linep4, "test4");
if (-1 == apphist(&hist, linep1)) {
perror("apphist() failed for line 1\n");
exit(EXIT_FAILURE);
}
if (-1 == apphist(&hist, linep2) {
perror("apphist() failed for line 2\n");
exit(EXIT_FAILURE);
}
if (-1 == apphist(&hist, linep3) {
perror("apphist() failed for line 3\n");
exit(EXIT_FAILURE);
}
if (-1 == apphist(&hist, linep4) {
perror("apphist() failed for line 4\n");
exit(EXIT_FAILURE);
}
{
size_t x = 0;
while (hist[x] != NULL) {
printf("%s\n", hist[x]);
++x;
}
}
}