在函数内分配内存后使用双指针
我正在使用C中的双指针,并且想知道我是否创建了一个初始化表的函数,当我尝试使用InitStringTable分配的内存时,它会在返回main时崩溃。 我相信一个简单的解决方法是使strTable全局化,然后我相信它没关系,但我不想这样做,因为这对我来说是一个学习练习,可以通过表格进行修改,即我应该能够修改strTable来自在InitStringTable之后的main或另一个函数modifyTable。 谢谢你提供的所有帮助。
int main() { char** strTable; // Allocates memory for string table. InitStringTable(strTable); // Below lines should be able to copy strings into newly allocated table. // Below lines cause crash however. strcpy(strTable[0], "abcdef"); strcpy(strTable[1], "xy"); } // Allocates memory for the string table. This function should create a table // of size 10 strings with each string 50 chars long. The code compiles fine. void InitStringTable(char** table) { int i = 0; table = (char**)malloc(sizeof(char)*10); for(i = 0; i < 10; i++) { table[i] = (char*)malloc(sizeof(char)*50); } for(i = 0; i < 10; i++) { memset(table[i], 0, 50); } strcpy(table[0], "string1"); }
C是按值传递的。
从InitStringTable()
返回时,分配给table
的值将丢失。
此外,当分配指向char
指针时,请求指向char
指针。
所以这:
... = (char**)malloc(sizeof(char)*10);
至少应该(假设C):
... = malloc(sizeof(char*)*10);
可能的方法是:
#include #include #include int InitStringTable(char *** ppptable, const size_t n, const size_t l) { int result = 0; if (NULL == ppptable) { result = -1; errno = EINVAL; } else { (*ppptable) = malloc(n * sizeof(**ppptable)); if (NULL == (*ppptable)) { result = -1; } else { size_t i = 0; for(; i < n; ++i) { (*ppptable)[i] = calloc(l, sizeof(*(*ppptable)[i])); if (NULL == (*ppptable)[i]) { result = -1; /* Failing in the middle requires clean-up. */ for (; i > 0; --i) { free((*ppptable)[i-1]); } free(*ppptable); (*ppptable) = NULL; break; } } } } return result; }
这样叫:
#include #include int InitStringTable(char *** ppptable, const size_t n, const size_t l); int main(void) { int result = EXIT_SUCCESS; char ** strTable = NULL; if ( -1 == InitStringTable(&strTable, 10, 42)) //* Allocate array with 10 "strings" à 42 chars. */ { perror("InitStringTable() failed"); result = EXIT_FAILURE; } else { strcpy(strTable[0], "abcdef"); strcpy(strTable[1], "xy"); } return result; }
不,我不会陷入这种荒谬的“你不想成为一名三星级程序员!” 讨论。
你有一个指针问题。
就像你说的那样:
void inc(int a){ a++; } int main(){ int a = 0; inc(a); printf ("%d\n", a); // will display 0, not 1 }
不起作用。
您必须将&strTable
而不是strTable
作为InitStringTable
参数传递,并因此更改InitStringTable
其他内容。
或者只是做strTable = InitStringTable()
; ,并从InitStringTable
返回一个char**
。
InitStringTable()下面的行崩溃,因为他们试图对内存地址执行操作,该内存地址与他们的范围不同,也没有任何引用
那个记忆地址。
函数InitStringTable()为表分配内存,但不能访问
调用函数(这里是main),因为内存是函数所在的本地
分配。
因此为了使用相同的内存地址进行操作
调用函数必须将该地址的引用传递给调用函数。
在您的程序中,您可以执行以下操作:
声明函数为: –
char **InitStringTable(char **); int main() { char** strTable; strTable = InitStringTable(strTable); strcpy(strTable[0], "abcdef"); strcpy(strTable[1], "xy"); } char **InitStringTable(char** table) { int i = 0; table = (char**)malloc(sizeof(char)*10); for(i = 0; i < 10; i++) { table[i] = (char*)malloc(sizeof(char)*50); } for(i = 0; i < 10; i++) { memset(table[i], 0, 50); } strcpy(table[0], "string1"); /* after the function has finished its job, return the address of the table */ return table; }