我正在学习C并尝试创建一个可以创建字符串数组的函数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parse(char ***aoa)
{
char *string = calloc(9, sizeof(char)); //create a string of size 8+1
strcpy(string, "hi world"); // put text in that array
char **array = calloc(10, sizeof(char *)); //create an array of strings
aoa = calloc(10, sizeof(char *)); //create and array of arrays
aoa[0] = array; //assign string array to the 0th elements of new array
array[0] = string; //assign our string to 0th element of string carry
printf("%s\n", aoa[0][0]); //print 0th element of 0th array.
}
int main()
{
char ***array = NULL;
parse(array);
printf("%s\n", array[0][0]);
return 1;
}
aoa(数组数组)位于堆上,因此两种方法应该相同。它打印&#34; hi world&#34;在解析函数中,但在main中给出了Segmentation Fault,我的代码有什么问题?
显然我需要释放()所有内容并进行错误检查,但我删除它以显示问题的要点
答案 0 :(得分:1)
您在parse()
中为局部变量保留空间,您需要从array
传递指向main
的指针,然后在函数内取消引用:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parse(char ****aoa)
{
char *string = calloc(9, sizeof(char)); //create a string of size 8+1
strcpy(string, "hi world"); // put text in that array
char **array = calloc(10, sizeof(char *)); //create an array of strings
*aoa = calloc(10, sizeof(char *)); //create and array of arrays
*(aoa[0]) = array; //assign string array to the 0th elements of new array
array[0] = string; //assign our string to 0th element of string carry
printf("%s\n", *(aoa[0][0])); //print 0th element of 0th array.
}
int main()
{
char ***array = NULL;
parse(&array);
printf("%s\n", array[0][0]);
return 1;
}
答案 1 :(得分:1)
悲惨的问题在于你的主要问题。您将变量数组作为值发送到解析函数,因此,它不会被解析更改并在MAIN中保持NULL。函数解析的原型应该是
void parse(char ****aoa)
你应该像以下一样把它发送到主要部门:
parse(&array)
但是你的代码过于复杂。尝试在别处启动数组数组,而不是在函数中传递指向它的指针。例如:
char ***getArray(void)
{
char ***ret; //the array you return
char *string = calloc(9, sizeof(char)); //create a string of size 8+1
strcpy(string, "hi world"); // put text in that array
char **array = calloc(10, sizeof(char **)); //create an array of strings
ret = calloc(10, sizeof(char ***)); //create and array of arrays
ret[0] = array; //assign string array to the 0th elements of new array
array[0] = string; //assign our string to 0th element of string carry
return (ret);
}
int main()
{
char ***array = getArray();
printf("%s\n", array[0][0]);
return (0);
}
顺便说一下,请务必确认您的分配没有失败。
答案 2 :(得分:1)
有一个合理的经验法则说,如果你发现自己需要两个以上的间接层,那么你的程序设计就很糟糕了。 (&#34;三星级节目&#34;)
您还使用基于指针的查找表而不是数组。这会导致分段并阻止您将分配的结果视为一块连续的内存。
最重要的是,您的代码还有其他几个问题。 我会考虑从头开始重写它,实际上使用多维数组。这是一个有效的例子:
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
bool create_string_array2d (size_t x,
size_t y,
size_t max_length,
char (**string_array)[x][y][max_length]);
void print_string_array2d (size_t x,
size_t y,
size_t max_length,
char string_array[x][y][max_length]);
static void fill_with_junk (size_t x,
size_t y,
size_t max_length,
char string_array[x][y][max_length]);
int main()
{
const size_t X = 9;
const size_t Y = 10;
const size_t MAX_CHARS = sizeof("hi world xx yy");
char (*array)[X][Y][MAX_CHARS];
bool result;
result = create_string_array2d(X, Y, MAX_CHARS, &array);
if(result == false)
{
printf("out of memory, halt & catch fire");
return 0;
}
fill_with_junk(X, Y, MAX_CHARS, *array);
print_string_array2d(X, Y, MAX_CHARS, *array);
free(array);
return 0;
}
bool create_string_array2d (size_t x,
size_t y,
size_t max_length,
char (**string_array)[x][y][max_length])
{
*string_array = calloc(1, sizeof(char[x][y][max_length]));
return string_array != NULL;
}
void print_string_array2d (size_t x,
size_t y,
size_t max_length,
char string_array[x][y][max_length])
{
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
printf("%s\n", string_array[i][j] );
}
printf("\n");
}
}
static void fill_with_junk (size_t x,
size_t y,
size_t max_length,
char string_array [x][y][max_length])
{
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
char junk [sizeof("hi world xx yy ")] = "hi world ";
char num [sizeof("xx ")];
sprintf(num, "%.2d ", (int)i);
strcat(junk, num);
sprintf(num, "%.2d", (int)j);
strcat(junk, num);
strcpy(string_array[i][j], junk);
}
}
}
答案 3 :(得分:0)
您永远不会在函数内取消引用aoa
,因此您只需覆盖参数的本地值。函数参数按C中的值传递。您也不需要分配两个字符串数组,这看起来并不正确。