char [1024] vs char *

时间:2010-07-04 19:31:51

标签: c char

我正在尝试研究C,而我正在使用char *和char数组来解决问题。我正在使用库中的通用哈希集容器(我不想详细描述)。该库包含函数

void *HashSetLookup(hashset *h, const void *elemAddr);

我必须使用它来搜索哈希集以查看该元素是否已经存在(哈希和比较函数是哈希集结构的一部分)。在这种情况下,我使用hashset来存储指向C字符串的指针,或者更具体地说(char * *)。我的问题是以下代码给出了分段错误:

    char word[1024];
    /* Some code that writes to the word buffer */
    HashSetLookup(stopList, &word);

虽然这段代码工作正常(并且符合预期):

    char word[1024];
    /* The same code as before that writes to the word buffer */
    char* tmp = strdup(word);
    HashSetLookup(stopList, &tmp);
    free(tmp);

我认为char word []和char *基本上是一回事。唯一的区别是char字[1024]在堆栈中的固定长度为1024,但堆中的tmp只占用了必要的空间(strlen(word)+1)。

因此我不明白为什么我必须在堆中复制字符串才能调用此函数。为什么会这样? char * tmp = strdup(“something”)和char word [1024] =“something”之间是否存在一些更基本的区别?

5 个答案:

答案 0 :(得分:6)

你提到你需要char **并且存在问题:对于数组,word&word意味着相同的事情 - 数组内容的实际位置。它使用指针时的工作原因是因为“指针”存储位于不同的位置,而指向指向同一个数组。您不需要strdup,只需创建一个指针:

char* tmp = word;
HashSetLookup(stopList, &tmp);

答案 1 :(得分:1)

没有HashSetLookup的文档很难说。

但是它期望const void *作为它的第二个参数,所以你应该传递tmp,而不是& tmp,因为tmp已经是一个指针。

我根本不认为需要char **。

此外,您可能对HashSetLookup()返回的内容感兴趣。

答案 2 :(得分:0)

你必须在第一个例子中遗漏了一些东西,因为根本没有使用“word”。

无论如何,在大多数环境中,当你编写'char * s =“Hello World”'时,它会在代码段上创建,无法修改。代码段意味着它是可执行代码的一部分,不能修改但只能读取。当你尝试编写它时,你会遇到一个段错误。

但是'char []'会在数据段上创建,因此可以毫无问题地进行修改。

答案 3 :(得分:0)

答案 4 :(得分:0)

由于你提到char**我认为问题在于试图的函数到第二个参数指向的位置,即你写的时候:

HashSetLookup( stopList, &word );

它会尝试为word分配一个地址(这就是为什么它需要它的地址。),它会用指针覆盖缓冲区。

以下愚蠢的片段证明了这一点(请记住,数组的地址仍然是其第一个元素的地址):

#include <stdio.h>
#include <stdlib.h>

void func( void* boo )
{
        char** ptr = ( char** )boo;
        printf( "func: got %p\n", boo );
        *ptr = "bad func";
}

int main( int argc, char* argv[] )
{
        char buf[128], *p;
        func( &buf ); /* buf got overwritten */
        printf( "array: %s\n", buf );
        p = malloc( 128 );
        func( &p ); /* p got new value */
        printf( "malloc: %s\n", p );
        return 0;
}