C-指针,数组和结构之间的交互

时间:2022-07-31 21:16:05

I've been reading up on pointers and arrays in C in an effort to learn how to implement something VLA-ish as a member of a struct. (Specifically, I need an array or array-like object with length different between instances of the struct but defined at compile-time for any particular struct instance.)

我一直在阅读C中的指针和数组,以学习如何实现VLA-ish作为结构的一部分。 (具体来说,我需要一个数组或类似数组的对象,结构实例之间的长度不同,但在编译时为任何特定的结构实例定义。)

It seems to me as though something like this:

在我看来好像这样:

typedef struct example{
    unsigned char length;
    char *data;
}example;

int buildExample(example e, unsigned char l, char * const d){
    e.length = l;
    e.data = d;
    return 0;
    //not safe I know, but that fact isn't relevant to the question.
}


main(){
    example e;
    unsigend char a = 5;
    char b[] = {1, 2, 3, 4, 5};
    buildExample(e, a, b);
    int i = 0;
    while(i < e.length){
        printf("%d  %d\n", i, e.b[i]);
        i++;
    }
    printf("%d  %d\n", i, e.b[i]);
}

should result in something like this output:

应该导致类似这样的输出:

0  1
1  2
2  3
3  4
4  5
5  some unknown value or a segfault, not sure which

and the various pointers and memory cells and such should go something like this:

和各种指针和内存单元格应该是这样的:

before call to buildExample:

example e.data                 b               address 0, 1, 2...
|null pointer|         |ptr to address 0|      |  1  |  2  |  3  |  4  |  5  |

after call to buildExample:

example e.data                  address 0, 1, 2...
|ptr to address 0|              |  1  |  2  |  3  |  4  |  5  |

But instead I just get a segfault. If I swap out e.data for b, I get the 'unknown value' outcome (32765, 32766 or 32767, for whatever reason), and if I swap out e.data for a new int* c, defined and set equal to b in main, I get the same result as b, which implies to me that e.data is not in fact being set to b by buildExample.

但相反,我只是得到一个段错误。如果我换掉e.data为b,我得到'未知值'结果(32765,32766或32767,无论出于何种原因),如果我换出e.data换新int * c,定义并设置等于b在main中,我得到与b相同的结果,这对我来说意味着e.data实际上并没有被buildExample设置为b。

Why not?

为什么不?

2 个解决方案

#1


2  

When calling buildExample() you're actually passing a copy of the e struct created in main(), so any changes will be lost when the function returns. Use a pointer instead.

在调用buildExample()时,实际上是在传递main()中创建的e结构的副本,因此当函数返回时,任何更改都将丢失。请改用指针。

int buildExample(example *e, unsigned char l, char * const d){
    e->length = l;
    e->data = d;
    return 0;
    //not safe I know, but that fact isn't relevant to the question.
}

And when calling:

并致电时:

buildExample(&e, a, b);

However you have other errors such as unsigend char a = 5; (should be unsigned not "unsigend") and trying to access an element named b (should be data).

但是你有其他错误,比如unsigend char a = 5; (应该是unsigned而不是“unsigend”)并尝试访问名为b的元素(应该是数据)。

buildExample(&e, a, b);
while(i < e.length){
    printf("%d  %d\n", i, e.data[i]);
    i++;
}
printf("%d  %d\n", i, e.data[i]);

Hope it helps!

希望能帮助到你!

#2


0  

This posted code presents a few problems.

这个发布的代码提出了一些问题。

1) the return type from main() is always int not a blank

1)main()的返回类型总是int而不是空白

2) the function: buildExample() modifies the e parameter (on the stack) but does not have any effect on the e variable back in the caller Should pass a pointer to the struct and change the assignments to e->length and e->data

2)函数:buildExample()修改e参数(在堆栈上),但对调用者中的e变量没有任何影响应该将指针传递给结构并将赋值更改为e-> length和e- >数据

3) use unsigned not unsigend`

3)使用unsigned not unigend`

4) the use of meaningless variable and parameter names makes the code unnecessarily difficult to understand

4)使用无意义的变量和参数名称使得代码不必要地难以理解

5) in the calls to printf() the example struct has no member b

5)在对printf()的调用中,示例struct没有成员b

Strongly suggest actually compiling the posted code before posting a question.

强烈建议在发布问题之前实际编译发布的代码。

typedef struct example
{
    unsigned char dataCount;
    char *pData;
} example;

void buildExample(example *pExample, unsigned char dataCount, char * const pData)
{
    pExample->dataCount = dataCount;
    pExample->pData = pData;
}


int main( void )
{
    example myExample;
    unsigned char dataCount = 5;
    char data[] = {1, 2, 3, 4, 5};

    buildExample(&myExample, dataCount, data);

    for( int i=0; i<myExample.count; i++)
    {
        printf("%d  %d\n", i, myExample.pData[i]);
    }
    printf("%d  %d\n", i, myExample.pData[i]);
}

#1


2  

When calling buildExample() you're actually passing a copy of the e struct created in main(), so any changes will be lost when the function returns. Use a pointer instead.

在调用buildExample()时,实际上是在传递main()中创建的e结构的副本,因此当函数返回时,任何更改都将丢失。请改用指针。

int buildExample(example *e, unsigned char l, char * const d){
    e->length = l;
    e->data = d;
    return 0;
    //not safe I know, but that fact isn't relevant to the question.
}

And when calling:

并致电时:

buildExample(&e, a, b);

However you have other errors such as unsigend char a = 5; (should be unsigned not "unsigend") and trying to access an element named b (should be data).

但是你有其他错误,比如unsigend char a = 5; (应该是unsigned而不是“unsigend”)并尝试访问名为b的元素(应该是数据)。

buildExample(&e, a, b);
while(i < e.length){
    printf("%d  %d\n", i, e.data[i]);
    i++;
}
printf("%d  %d\n", i, e.data[i]);

Hope it helps!

希望能帮助到你!

#2


0  

This posted code presents a few problems.

这个发布的代码提出了一些问题。

1) the return type from main() is always int not a blank

1)main()的返回类型总是int而不是空白

2) the function: buildExample() modifies the e parameter (on the stack) but does not have any effect on the e variable back in the caller Should pass a pointer to the struct and change the assignments to e->length and e->data

2)函数:buildExample()修改e参数(在堆栈上),但对调用者中的e变量没有任何影响应该将指针传递给结构并将赋值更改为e-> length和e- >数据

3) use unsigned not unsigend`

3)使用unsigned not unigend`

4) the use of meaningless variable and parameter names makes the code unnecessarily difficult to understand

4)使用无意义的变量和参数名称使得代码不必要地难以理解

5) in the calls to printf() the example struct has no member b

5)在对printf()的调用中,示例struct没有成员b

Strongly suggest actually compiling the posted code before posting a question.

强烈建议在发布问题之前实际编译发布的代码。

typedef struct example
{
    unsigned char dataCount;
    char *pData;
} example;

void buildExample(example *pExample, unsigned char dataCount, char * const pData)
{
    pExample->dataCount = dataCount;
    pExample->pData = pData;
}


int main( void )
{
    example myExample;
    unsigned char dataCount = 5;
    char data[] = {1, 2, 3, 4, 5};

    buildExample(&myExample, dataCount, data);

    for( int i=0; i<myExample.count; i++)
    {
        printf("%d  %d\n", i, myExample.pData[i]);
    }
    printf("%d  %d\n", i, myExample.pData[i]);
}