Проблема с указателем для начинающего - PullRequest
2 голосов
/ 06 июня 2011

Я новый пользователь C, у которого проблемы с указателями.

Функция add_word (* word_to_add) должна взять строку ac и добавить ее в соответствующий связанный список word_node.Однако последующие добавления, кажется, перезаписывают элемент word всех узлов в хеш-таблице.Я думаю, что это происходит потому, что я устанавливаю для каждого элемента word узла указатель на word_to_add, а не копирую значение word_to_add.

#define HASH_TABLE_SIZE 10
static char **word_list;

struct word_node {
    char* word;
    struct word_node *next;
};

static struct word_node *word_hash_table[HASH_TABLE_SIZE];

static int hash(char *word) {
    int ascii_char;
    int key;

    key = 0;
    while (*word != '\0') {
        ascii_char = tolower(*word);
        key += ascii_char;
        word++;
    }
    key %= HASH_TABLE_SIZE;
    return key;
}


void ws_add_word(char *word_to_add)
{
    int word_position;


    word_position = hash(word_to_add);

    if (word_hash_table[word_position] == NULL)
    {
        struct word_node* p;
        p = malloc(sizeof(struct word_node));;
        p->word = word_to_add;
        p->next = NULL;
        word_hash_table[word_position] = p;
        ++num_words;
    } else {
        struct word_node* p;
        p = word_hash_table[word_position];

        while (p->next != NULL)
        {   
            p = p->next;
        }

        struct word_node* q;
        q = malloc(sizeof(struct word_node));
        q->word = word_to_add;
        q->next = NULL;
        p->next = q;
        ++num_words;
    }

Ответы [ 4 ]

1 голос
/ 06 июня 2011

Я думаю, что ваш код в порядке, как есть.Если у вас возникли проблемы, это может быть связано с тем, как вы вызываете функцию.Например, вот быстрый и грязный пример:

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

int num_words;

/* paste sample code here */
#define HASH_TABLE_SIZE 10
// rest of code
void ws_add_word(char *word_to_add)
{
    // function code
}
/* end of sample code */

int main (void)
{
    char a[] = "Hello";
    char b[] = "Helkp"; // chosen to have the same hash result

    ws_add_word((char *)&a);
    ws_add_word((char *)&b);

}

Я скомпилировал с gcc -g и пробежал по gdb.Делая это, проходя через ws_add_word и просматривая содержимое word_hash_table, похоже, получаешь то, что хочешь.Если это все еще не работает, вы должны привести пример того, как вы звоните ws_add_word.

Кроме того, если вы просто измените p->word = word_to_add на strcpy(p->word,word_to_add), вы, вероятно, получите ошибку сегмента, потому чтоp->word пока не настроен на что-либо значимое.Вам нужно p->word = (char *)malloc(N), где N достаточно велик, а затем strcpy, если вы действительно этого хотите.То, хотите вы этого или нет, зависит от того, будет ли место памяти, на которое указывает char *word_to_add, действительным в следующий раз, когда вам понадобится его использовать.

0 голосов
/ 27 декабря 2013

Кажется, что указатель на символ в узле «word» указывает на исходную строку, а не на собственную копию.Это хорошо, если исходная строка не изменяется.Например:

//Assume word_to_add is "String 1"

p->word = word_to_add;

//Now change word_to_add to "String 2"
//After this p->word would be "String 2"

Я не знаю, было ли это предполагаемым поведением.Возможно, вы захотите выделить память для каждого указателя слова в структуре узла и скопировать строку word_to_add.

0 голосов
/ 06 июня 2011

Вы не можете просто приравнять две строки или символьные указатели, например:

char* p1, p2;
p1=p2; // THIS IS INVALID

В своем коде вы совершили эту ошибку два раза: -

p->word = word_to_add;

и

q->word = word_to_add;

Это говорит о том, что вы указываете p-> word на word_to_add, который является указателем. Он просто начнет ссылаться на тот же объект, но не будет копировать ожидаемую строку.Он не скопирует содержимое word_to_add в q-> word, что, как вы предполагаете, будет сделано.

Вам необходимо скопировать строки, используя любую функцию копирования строк, например: strcpy, strncpy или memcpy.

заменить p-> word = word_to_add на

strcpy(p->word,word_to_add);

и аналогично

заменить q-> word = word_to_add на

strcpy(q->word,word_to_add);

-

Кр.Alok

0 голосов
/ 06 июня 2011

Хорошо выглядит для меня, за исключением строки 10 в ws_add_word.

Изменение

q->word = word_to_add; 

до

p->word = word_to_add; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...