如何传递指针并在堆上分配空间

我试图向一个函数提供一个char指针,然后用它填充它,以便调用函数可以使用它。 因为它总是在调用函数中给我奇怪的东西,我写了一个关于我所做的简单表示:

#include  #include  void bla(char *t) { t = (char*) malloc(5); if (t != 0) { t[0] = 'h'; printf("%c\n", t[0]); } } int main(int argc, char **argv) { char b[10]; bla(b); printf("%c\n", b[0]); return 1; } 

我不太确定C传递参数副本是否有事可做。 我需要将指针传递给指针,还是有更好的解决方案?

编辑:

对不起的家伙,但我没有得到它。 你能看一下这个例子:

 #include  #include  void blub(char **t) { printf("%d\n", *t); *t = (char*) malloc(sizeof(char) * 5); *t[0] = 'a'; *t[1] = 'b'; printf("%d\n", *t); printf("%d\n", *t[0]); printf("%d\n", *t[1]); } int main(int argc, char **argv) { char *a; blub(&a); printf("%d\n", a); printf("%d\n", a[0]); printf("%d\n", a[1]); return 1; } 

输出如下:

 ./main 6154128 140488712 97 98 140488712 97 0 <== THIS SHOULD BE 98 AS ABOVE!? 

为什么我在函数blafu中获得98,而在main中它是一个空指针?! 我完全糊涂了:/

你需要使用指针指针。

 //............vv void bla(char **t) 

然后通过解引用它来使用指针:

 // note the '*' in front of t *t = (char*) malloc(5); if (*t != 0) { *t[0] = 'h'; printf("%c\n", *t[0]); } 

另外,将b声明为char* ,而不是char b[10]


为什么? 因为你正试图改变指针。 逻辑与其他类型相同,但这里有点令人困惑。
想想这样:如果你需要传递一个int而你需要更改它,你需要一个指向int指针 。 同样在这里 – 你需要传递一个指向char指针 ,你需要你改变它,所以使用“ 指向char的指针 ”:)


编辑 :根据您的编辑 – 是的,您完全理解这一点,只有一个小问题 – operator*operator[]的优先级。 如果用(*t)[X]替换你的*t[X] (*t)[X] ,每个都可以正常:)

如果使用指针指针

 void blah(char **t) 

你可以使用malloc as来分配一个内存块(在头部)

 *t = malloc(size); 

你会这样称呼blah:

 char *b; bla(&b); 

它将被分配并用blah填充,结果可以打印在main中。

你正在传递一个指向函数的指针。 通过它,你可以永久地改变(在函数返回之后)只指向它指向的对象,但你不能改变指针本身,因为它是实际传递给函数的副本。 函数内的所有更改都在指针的副本上进行。 当函数返回时,其原始值保持不变。

(1)如果要在某个函数中更改某个变量,则需要将其指针传递给它。 如果该变量是指针类型,则传递一个指向它的指针 – 一个指向指针的指针! 在您的情况下,该变量将是char **类型。

(2)如果要在函数中的堆上分配内存,则不需要使用堆栈 – 将指针b声明为char *。

(3)在堆上分配内存后,不要忘记解除分配,否则最终会导致内存泄漏。

(4)如果应用程序终止且没有错误,则从应用程序返回0。 保留错误代码的其他返回值 – 如果您的应用中可能出现不同的错误,请返回不同的代码。

最后一点是这是一个纯C应用程序。 在C ++中,您将使用new / delete来分配/释放内存,std :: string而不是char *用于字符串,而std :: cout <<而不是printf用于将文本发送到输出流

 void bla(char **pt) // (1) { *pt = (char*)malloc(5); if (*pt != 0) { *pt[0] = 'h'; printf("%c\n", *pt[0]); } } int main(int argc, char **argv) { char* b = 0; // (2) bla(&b); printf("%c\n", b[0]); if(b) { free(b); // (3) b = 0; } return 0; // (4) } 

当你写char b[10]; 如果你有一个静态分配的数组,你不需要为它分配更多的空间,它最多可以容纳10个char值。

如果你想让你的函数修改那个数组的内容,你只需要传递一个简单的指针(但没有分配!):

 void bla(char *t) { if (t != 0) { t[0] = 'h'; printf("%c\n", t[0]); } } 

在该function之后, mainb值也会发生变化。

如果你想使用var引用返回结果然后是,你必须将指针传递给指针,(或者只是以通常的方式返回结果,char * bla())。 不要忘记null终止符!

第二个例子中出现奇怪行为的原因是运营商的优先级。 [](括号,数组下标)的优先级高于*(取消引用)

因此, *t[1]*(t[1]). 你需要(*t)[1]

因为t是指向char的指针:

*(t[1])表示“将t的地址,go(sizeof(char *))字节提前,取消引用地址,然后再取消引用”

(*t)[1]表示“取t的地址,取消引用它,go(sizeof(char))字节前进并再次取消引用”

实际上在第一种情况下,行为是未定义的,因为它试图在t之后双重取消对位置的影响。 在您的示例中,将始终打印第一个值,因为t [0]仅表示取消引用,因此两个案例将是相同的。