【问题标题】:What am I doing wrong in passing a struct around in C?在 C 中传递结构时我做错了什么?
【发布时间】:2020-02-08 20:32:35
【问题描述】:

所以我正在使用 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
É·/¨

显然,该程序不仅仅包含我在这里写的内容;这只是一个简化版本;所以如果有什么我应该检查可能导致这种情况的原因,请告诉我。老实说,我认为这可能只是我在某个地方犯的一个愚蠢的新手错误。

[编辑:似乎s.thing1 在对function_2() 的调用中以某种方式发生了变异,因为在main() 中复制了奇数值——我应该指出,在我的程序中printf()s 是位于函数调用之前和函数的第一行,所以它不可能被我正在做的任何事情写入。我已经更新了上面的示例代码以显示这一点。]

提前致谢!

【问题讨论】:

  • 这不是有效的 C 代码。它无法编译。
  • char thing1[]; 无效。灵活数组成员必须struct 的最后一个成员。
  • 抱歉,这是我代码中的最后一个成员 - 现在将交换它@user3386109
  • 除非必须将字符串存储在结构本身中,否则更常见的做法是将指针作为结构的成员,并为字符串单独分配内存。灵活的数组成员需要程序员非常小心,对于刚开始使用该语言的人来说可能不是一个好的选择。
  • @NateEldredge 谢谢你的建议;我目前正在使用 chqrlie 的方法,但如果遇到问题,我会尝试单独的字符串!

标签: c pointers struct reference


【解决方案1】:

该结构在其末尾包含一个灵活的成员,如果您声明一个具有该类型的静态对象,该成员的长度将为零,因此strcpy(s->thing1, "Hello"); 将具有未定义的行为。

您应该为此类结构的实例分配足够的额外空间来处理您希望存储到灵活数组中的任何数据。

这是一个例子:

#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;
}

【讨论】:

  • 好的 - 如果我确实需要为此设置动态大小,那么最好的选择是什么?该值来自用户输入,可以是任意长度。
  • @barnstorm3r:查看更新答案中的示例。
  • 会的;谢谢!我是 C 新手,所以不知不觉地对使用 malloc() 有点警惕,因为它对我来说有点陌生,但我现在就来看看。再次感谢!
  • 刚刚实现;完美运行,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
  • 2021-02-23
相关资源
最近更新 更多