Узлы C - как не перезаписать выделенное пространство памяти, а создать новое (домашнее задание) - PullRequest
0 голосов
/ 11 декабря 2010

Структура компании определяется следующим образом:

typedef struct company {
 char* company_name;
 int employee_counter;
} company;

Я использую эту функцию для создания нового узла компании:

company *make_company_node(char* company_name, int employee_counter) {
 company *newNode = (company*) malloc(sizeof(company));
 if(!newNode) return NULL; 

 newNode->company_name = company_name;
 newNode->employee_counter = employee_counter;

 return newNode;
}

Затем я получаю несколько названий компаний из входных данных, создаю узел компании для каждого из них:

companyUnion->company_arr[i] = make_company_node(company_name, 0);

(company_arr в конечном итоге содержит указатели на все компании).

Проблема в том, что мне кажется, что я всегда перезаписываю первоначально выделенное пространство памяти, и поэтому в конце я получаю массив, все ячейки которого указывают на последнюю компанию (с отправленной фамилией).

Как я могу исправить это, чтобы он не перезаписывал, а вместо этого всегда выделял новое место?

Ответы [ 4 ]

1 голос
/ 11 декабря 2010

Если, как упоминалось в pmg, вы заранее знаете длину строки или если существует известное максимальное количество символов, которое вы можете установить, предпочтите вместо определения company_name в качестве статического массива:

char company_name[MAX_LENGTH];

Это уменьшит объем управления памятью, которое вам нужно сделать, а также возможные ошибки, которые вы только что испытали.

1 голос
/ 11 декабря 2010

Если вы знаете длину company_name до вызова вашей функции make_company_node, я бы изменил функцию, чтобы она принимала эту длину (в противном случае используйте strlen).

company *make_company_node(char *company_name, size_t cn_len, int employee_counter) {
    company *newNode = malloc(sizeof *newNode);
    if (newNode) {
        newNode->company_name = malloc(cn_len + 1);
        if (newNode->company_name) {
            strcpy(newNode->company_name, company_name);
            newNode->employee_counter = employee_counter;
        } else {
            free(newNode);
            newNode = NULL;
        }
    }
    return newNode;
}

Я предпочитаю делать это с malloc и strcpy вместо strdup, поскольку strdup не определено Стандартом (хотя оно определено в POSIX), и использование strdup.

не дает никаких преимуществ.
0 голосов
/ 11 декабря 2010

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

newNode->company_name = strdup(company_name);

Не забудьте free() потом.

0 голосов
/ 11 декабря 2010

Хм, похоже, проблема в переменной company_name.Это указатель на фактические данные названия компании.Как вы распределяете эти данные?Вы уверены, что это правильный указатель?Может быть, вам нужно что-то вроде этого:

newNode->company_name = strdup(company_name);

strdup дублирует строку, которую вы ей передаете, динамически.Не забудьте освободить его.

Это распространенная ошибка, поскольку company_name содержит адрес некоторых данных.Если используется один и тот же адрес и данные внутри него изменяются, вы получите разные результаты, поэтому вам необходимо сделать его копию.

...