2011-10-28 37 views
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; 
} 

我不太清楚,如果有事情做的是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; 
} 

输出如下:

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

为什么我得到的功能blafu 98和主要它是一个空指针?我很困惑:/

+0

该代码没什么意义... –

+1

不要忘记释放你的记忆! – Nick

+0

@pluckyDuck - 看我的编辑:)你是在正确的方向。 –

回答

7

你需要使用指针指针。

//............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]); 
} 

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


为什么?因为你正试图改变指针。逻辑与其他类型相同,但这里有点混乱。
想想这样:如果你需要通过一个int并且你需要改变它,你需要一个指向int的指针。同样是在这里 - 你需要传递一个字符指针,你需要改变哟,所以用“指针字符指针” :)


编辑: 根据你的编辑 - 是的,你完全理解这一点,这只是一个小问题 - 优先operator*operator[]。如果您*t[X](*t)[X]取代,当你写char b[10];你有一个静态分配的数组,你并不需要分配更多的空间,它是适合容纳多达10 everythng将被罚款:)

+0

你拯救了我的生命:) – pluckyDuck

0

值为char

如果你想让你的函数修改数组,你只需要通过一个简单的指针的内容,你都做到了(但没有配置!):

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

的功能后,您的main中的b的值也会更改。

+0

它只是真正的问题的模型,我需要使用malloc。 – pluckyDuck

2

如果你使用指针的指针

void blah(char **t) 

您可以使用malloc作为

*t = malloc(size); 

分配的内存chunck(在头),你会打电话等等这样的:

char *b; 
bla(&b); 

它将被分配和填充使用等等,结果可以打印在主要。

0

如果你想使用var引用返回结果,那么你需要传递一个指针指向一个指针(或者只是以通常的方式返回结果char * bla())。不要忘记null结束符!

1

您正在传递指向函数的指针。通过它,你可以永久地改变(在函数返回之后)它所指向的对象,但是你不能改变指针本身,因为它是实际传递给函数的副本。函数内的所有更改都是在指针的副本上进行的。函数返回时其原始值保持不变。 (1)如果你想在一些函数中改变一些变量,你需要将它的指针传递给它。如果该变量是指针类型的,则将指针传递给它 - 指向指针的指针!在你的情况下,该变量将是char **类型。 (2)如果你想在函数的堆中分配内存,你不需要使用堆栈 - 将指针b声明为char *。 (3)在堆上分配内存之后,不要忘记取消分配它,否则最终会发生内存泄漏。

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

最后一点是,这是一个纯粹的C应用程序。在C++中,你将使用新/删除分配/释放内存,的std :: string代替字符*字符串,和std ::法院< <代替了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) 
} 
0

的第二个例子中奇怪行为的原因是操作员的优先级。 [](括号,数组下标)具有比*更高的优先级(解引用)

所以,*t[1]相同*(t[1]).需要(*t)[1]

为t是指向字符指针:

*(t[1])意味着“取得t的地址,前进(sizeof(char *))字节,取消引用地址,并且解除引用”

(*t)[1]意思是“取得t的地址,取消引用它,去(sizeof(char))字节提前并取消e再次“

实际上,在第一种情况下,行为是未定义的,因为它试图在t之后将位置加倍去保护。在你的例子中,第一个值总是会被​​打印出来,因为t [0]意味着只有解引用,所以这两种情况将是相同的。

相关问题