【问题标题】:strcpy / strncmp segmentation fault in struct fileds结构字段中的 strcpy / strcmp 分段错误
【发布时间】:2014-12-27 17:40:17
【问题描述】:

我正在尝试将新节点添加到具有 char* 字段(单词)的结构中

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 时,它有时可以正常工作。

【问题讨论】:

  • 你确定curr = head->next那个head->next不为NULL吗?因为在这种情况下 curr->word 肯定会给出段错误。是的,这就是问题所在。
  • 我添加了一个 if 语句来中断 for 循环,以防 curr == NULL 但仍然出现相同的段错误。
  • 在您的for 循环中,我会检查curr 的有效性,而不仅仅是在else 中重新分配它:for (cur = head->next; curr->next; curr = curr->next) 会更安全一些
  • 我按照你的建议进行了更改,但我仍然得到 seg。 for (curr = head->next; curr->next != NULL; curr = curr->next) if(curr == NULL) break; if(strncmp(curr->word,newnode->word,strlen(word)) > 0) break;
  • 首先,在问题中发布相关信息,而不是在 cmets 中。其次,我没有想到这个函数是你的整个程序。我试图礼貌地暗示您没有发布回答您的问题所需的所有相关信息。你至少应该显示你调用这个函数的参数。

标签: c struct char strncpy strncmp


【解决方案1】:

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

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

在写东西之前应该给指针分配内存。

【讨论】:

  • 这不是:newnode = (listT *) malloc(sizeof(listT) + WORDLEN); 为 char* 字分配内存吗?
  • @user3163175 我看不到代码中的 WORDLEN 是什么,但不需要它,只需为您的结构分配内存并为结构分配内存即可
  • 感谢您的信息。我更改了它,但我认为这不能解决问题,因为 WORDLEN 比单词的实际长度大。
  • @user3163175 请分配内存来保存WORDLEN检查编辑
  • 我做了,但没有任何改变
【解决方案2】:

稍微扩展@Gopi的答案:

你的陈述

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

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

TL;DR:这个WORDLEN 内存不会分配给newnode->word,而是分配给newnode,就是这样。要解决您的问题,您必须单独为newnode->word 分配内存。 newnode 不需要该内存,但 newnode->word 需要。

strndup() 之所以有效,是因为它会为您分配内存。

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

newnode->word 是一个指针。它在特定机器上具有固定大小(例如 8 个字节)。为简单起见,假设listT 定义如下:

typedef struct {
    char *word;
} listT;

那么你在分配内存的时候,只需要给newnode分配8个字节,这样它就可以容纳一个指针,然后你就需要给那个指针分配内存,用来存放一些字符。


虽然与您的问题无关,但我还想指出,您不应该转换 malloc() 的返回值。见Do I cast the result of malloc?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 2015-08-14
    • 2011-11-11
    • 2020-10-05
    相关资源
    最近更新 更多