Что я делаю неправильно, передавая структуру в C? - PullRequest
1 голос
/ 08 февраля 2020

Итак, я работаю над проектом в C, который требует, чтобы я передавал указатели на структуру в функции. Проект структурирован следующим образом:

struct structName {
    unsigned short thing2;
    char thing1[];
};

void function_1(struct structName *s) {
    strcpy(s->thing1, "Hello");
    printf("Function 1\n%s\n\n", s->thing1); // prints correctly
}

void function_2(struct structName *s) {
    // can read thing2's value correctly
    // thing1 comes out as a series of arbitrary characters
    // I'm guessing it's an address being cast to a string or something?

    printf("Function 2\n%s\n\n", s->thing1); // prints arbitrary characters ('É·/¨')
}

int main() {
    struct structName s;
    function_1(&s);
    printf("Main\n%s\n\n", s.thing1);
    function_2(&s);
    printf("Main 2\n%s\n\n", s.thing1);
}

Этот код выводит следующее:

Function 1
Hello

Main
Hello

Function 2
É·/¨

Main 2
É·/¨

Очевидно, что в программе есть нечто большее, чем то, что я здесь написал; это просто упрощенная версия; так что если есть что-то, что я должен проверить, это может быть причиной, дайте мне знать. Честно говоря, я считаю, что это, вероятно, просто глупая ладья ie ошибка, которую я делаю где-то.

[РЕДАКТИРОВАТЬ: Кажется, s.thing1 каким-то образом мутирует в вызове function_2(), так как нечетное значение реплицируется в main() - я должен указать, что в моей программе printf() расположены непосредственно перед вызовом функции и в первой строке функции, поэтому нет никаких шансов, что она будет записана кем-либо Я делаю. Я обновил приведенный выше пример кода, чтобы показать это.]

Заранее спасибо!

1 Ответ

2 голосов
/ 08 февраля 2020

Структура содержит гибкий элемент в конце, если вы объявите объект stati c с этим типом, длина этого члена будет равна нулю, поэтому strcpy(s->thing1, "Hello"); будет иметь неопределенное поведение.

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

Вот пример:

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

typedef struct pstring {
    size_t length;
    char data[];
} pstring;

pstring *allocate_pstring(const char *s) {
    size_t length = strlen(s);
    pstring *p = malloc(sizeof(*p) + length + 1);
    if (p != NULL) {
        p->length = length;
        strcpy(p->data, s);
    }
    return p;
}

void free_pstring(pstring *p) {
    free(p);
}

int main() {
    pstring *p = allocate_pstring("Hello");
    printf("Main\n%.*s\n\n", (int)p->length, p->data);
    free_pstring(p);
    return 0;
}
...