C 如何传递指针并在堆上分配空间
我试图传递一个指向函数的char指针,然后用东西填充它,以便调用函数可以使用它。由于调用函数总是给我一些奇怪的东西,我写了一个关于我所做工作的简单表示:C 如何传递指针并在堆上分配空间,c,pointers,C,Pointers,我试图传递一个指向函数的char指针,然后用东西填充它,以便调用函数可以使用它。由于调用函数总是给我一些奇怪的东西,我写了一个关于我所做工作的简单表示: #include <stdio.h> #include <stdlib.h> void bla(char *t) { t = (char*) malloc(5); if (t != 0) { t[0] = 'h'; printf("%c\n", t[0]); }
#include <stdio.h>
#include <stdlib.h>
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;
}
#包括
#包括
无效bla(字符*t)
{
t=(char*)malloc(5);
如果(t!=0){
t[0]='h';
printf(“%c\n”,t[0]);
}
}
int main(int argc,字符**argv)
{
charb[10];
bla(b);
printf(“%c\n”,b[0]);
返回1;
}
我不太确定它是否与C传递参数副本有关。我是否需要将指针传递给指针,还是有更好的解决方案
编辑:
对不起,伙计们,我没听懂。你能看一下这个例子吗
#include <stdio.h>
#include <stdlib.h>
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;
}
#包括
#包括
无效blub(字符**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,字符**argv)
{
char*a;
blub&a;
printf(“%d\n”,a);
printf(“%d\n”,a[0]);
printf(“%d\n”,a[1]);
返回1;
}
结果如下:
./main
6154128
140488712
97
98
140488712
97
0 <== THIS SHOULD BE 98 AS ABOVE!?
/main
6154128
140488712
97
98
140488712
97
0您需要使用指针对指针
//............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]
,一切都会好起来:)当您编写字符b[10]
您有一个静态分配的数组,不需要为它分配更多的空间,最多可以容纳10个char
值
如果您想让函数修改该数组的内容,只需在传递过程中传递一个简单的指针(但不需要分配!):
函数完成后,main
中的b
的值也会更改。如果使用指向指针的指针
void blah(char **t)
您可以使用malloc作为
*t = malloc(size);
你会这样称呼布拉:
char *b;
bla(&b);
它将在blah中分配和填充,结果可以在main中打印。如果您想使用var引用返回结果,那么是的,您必须将指针传递给指针(或者只需以通常的方式返回结果,char*bla()。不要忘记空终止符 您正在向函数传递指针。通过它,您可以永久地(在函数返回后)只更改它指向的对象,但您不能更改指针本身,因为实际上传递给函数的是它的副本。函数内部的所有更改都是在指针的副本上进行的。当函数返回时,其原始值保持不变
(1) 如果要更改某个函数中的某个变量,需要将其指针传递给它。如果该变量是指针类型,则传递一个指向它的指针-指向指针的指针!在您的情况下,该变量的类型为char**
(2) 如果要在函数的堆上分配内存,则不需要使用堆栈-将指针b声明为char*
(3) 在堆上分配内存后,不要忘记取消分配,否则最终会导致内存泄漏
(4) 如果应用程序终止时没有错误,则从应用程序返回0。保留其他返回值
对于错误代码-如果应用程序中可能出现不同的错误,请返回不同的代码
最后一点是,这是一个纯C应用程序。在C++中,您将使用NeX/DELT分配/释放内存、STD::String,而不是CHAR*字符串,而STD::CUT第二个示例中奇怪行为的原因是操作符的优先级。
[](括号,数组下标)的优先级高于*(取消引用)
因此,*t[1]
与*(t[1])相同。
您需要(*t)[1]
因为t是指向char的指针:
*(t[1])
的意思是“取t的地址,前进(sizeof(char*))字节,取消对地址的引用,然后再次取消引用”
(*t)[1]
表示“获取t的地址,取消引用,向前移动(sizeof(char))字节,然后再次取消引用”
实际上,在第一种情况下,behavious是未定义的,因为它试图在t之后加倍解除对位置的限制。在您的示例中,将始终打印第一个值,因为t[0]表示仅取消引用,因此这两种情况将是相同的。这段代码没有什么意义……别忘了在某个地方释放内存@PullyDuck-请看我的编辑:)你的方向正确。这只是一个真正问题的模型,我需要使用malloc。
char *b;
bla(&b);
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)
}