struct字段中的strcpy / strncpy分段错误

时间:2014-12-27 17:40:18

标签: c struct char strncpy strncmp

我正在尝试使用char * field(word)

向结构添加新节点
  

listT的定义:

enum boolean {false, true};
struct list {
    enum boolean sorted;
    union{
        int words;
        char *word;
    };
    struct list* next;
    struct list* previous;
};
typedef struct list listT;

add_word_node函数由main调用为:add_word_node(read_word, list_head) 其中read_word由用户使用scanf给出。 Word作为字符串传递但在strncpy之后没有终止字节。

>Debugger:
     add_word_node (word=0xbffff0fa "ally", head=0x804c038) at prog.c    
>Debugger:
     (gdb) p newnode->word


     $2 = 0x804c068 "allyP\224\373\267\377\377\377\377" 




 listT *add_word_node(char word[], listT *head) {
    listT *newnode;
    listT *curr = NULL;//sorted
    //listT *prev;//sorted

    newnode = malloc(sizeof(listT)); /* allocate new node and check */
    newnode->word = malloc(sizeof(char)* WORDLEN);
    strncpy(newnode->word, word, strlen(word));
    //newnode->word = strndup(word, strlen(word));


    if (newnode == NULL) {
        return (NULL);
    }

    if (head->sorted == false){ //eisagwgh sto telos ths listas
        newnode->next = head;
        head->previous->next = newnode;
        newnode->previous = head->previous;
        head->previous = newnode;
    }else {
        if(head->next == head){
            newnode->next = head;
            newnode->previous = head;
            head->next = newnode;
            head->previous = newnode;

        }else{
            for (curr = head->next; curr->next != NULL; curr = curr->next){//for( curr = head->next; ;){
                if(curr == NULL) break;
                if(strncmp(curr->word,newnode->word,strlen(word)) > 0) break;
                //else curr= curr->next;
            }
            if(strncmp(curr->word,newnode->word,strlen(word))== 0){
                return(curr);
            }
            newnode->next = curr;
            newnode->previous = curr->previous;
            newnode->previous->next = newnode;
            newnode->next->previous = newnode;
        }
    }

    return (newnode);

}

我已经阅读了有关此问题的其他一些主题,并且我将函数更改为使用word []而不是char *,但它仍然无效。如果您需要更多信息,请告诉我。 此外,当我使用strndup时,它有时可以正常工作。

2 个答案:

答案 0 :(得分:0)

如你所说,你有一个char *word,那么这个指针应该被分配内存

newnode->word = malloc(sizeof(char) * (WORDLEN+1)); /* Please access the structure elements accordingly */

在向内容写入内容之前,应将内存分配给指针。

答案 1 :(得分:0)

要扩大@Gopi的答案:

您的陈述

newnode = (listT *) malloc(sizeof(listT) + WORDLEN);

将内存分配给指针newnode。这意味着,例如,如果WORDLENsizeof(listT)相同,那么您将为listT的两个newnode元素分配内存。这类似于char *ptr = malloc(2);,它会为char的两个ptr元素分配内存。

TL; DR:此WORDLEN内存不会分配给newnode->word,而是分配给newnode,以及newnode->word。要解决您的问题,您必须单独为newnode分配内存。 newnode->word不需要那个记忆,但strndup()会这样做。

newnode->word有效,因为它会为您分配内存。

如果你仍然很难理解这一点,你可能会对指针有一些误解。

listT是一个指针。它在某台机器上具有固定的大小(例如8字节)。为简单起见,假设typedef struct { char *word; } listT; 定义如下:

newnode

然后,当你分配内存时,你只需要为malloc()分配8个字节,这样它就可以容纳一个指针,然后你需要为该指针分配内存,这将用于存储一些字符。

<小时/> 虽然与您的问题无关,但我还想指出您不应该转换{{1}}的返回值。请参阅Do I cast the result of malloc?