指向结构的指针,字段莫名其妙地改变了价值观

时间:2014-10-08 17:33:30

标签: c pointers structure

我已经做好充分的准备,被告知我做了一些愚蠢/错误的事;这就是我的期望。

在从指针访问字段时,我感觉到了结构并且变成了一个裁剪器。代码要遵循。

matrix.h:

#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED

#include <stdlib.h>

typedef struct
{
    size_t size;
    int* vector;
} vector_t;

#endif // MATRIX_H_INCLUDED

main.c中:

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

#include "matrix.h"

vector_t* vector_new(size_t size)
{
    int vector[size];
    vector_t v;
    v.size = size;
    v.vector = vector;
    return &v;
}

int main(int argc, char* argv[])
{
    vector_t* vec = vector_new(3);
    printf("v has size %d.\n", vec->size);
    printf("v has size %d.\n", vec->size);

    return EXIT_SUCCESS;
}

所以这是一个非常简单的程序,我创建一个大小为3的向量结构,返回指向结构的指针,然后打印它的大小。在第一个打印实例上,这是3,然后在下一个打印时更改为2686668。发生了什么事?

提前致谢。

2 个答案:

答案 0 :(得分:1)

您正在从v返回指向局部变量vector_new的指针。这没有丝毫的工作机会。到vector_new返回main时,所有局部变量都被销毁,指针指向无处。此外,内存v.vector指向的也是本地数组vector。当vector_new返回时,它也会被销毁。

这就是您看到printf打印垃圾的原因。

您的代码必须在内存管理方面进行全面重新设计。必须使用malloc动态分配实际数组。 vector_t对象本身可以动态分配,也可以在main中声明为局部变量,并传递给vector_new进行初始化。 (您想要遵循哪种方法取决于您)。

例如,如果我们决定使用动态分配来完成所有事情,那么它可能如下所示

vector_t* vector_new(size_t size)
{
   vector_t* v = malloc(sizeof *v);
   v->size = size;
   v->vector = malloc(v->size * sizeof *v->vector);
   return v;
}

(不要忘记检查malloc是否成功。)

但是,我们动态分配的所有内容都必须稍后使用free解除分配。因此,您必须为此目的编写vector_free函数。

答案 1 :(得分:0)

完成重写 的回答以解决您的问题,并提供替代方法:

OP中编写的代码无法编译:&amp; v是非法返回值。

如果我修改你的代码:

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

typedef struct
{
    size_t size;
    int* vector;
} vector_t;

vector_t* vector_new(size_t size)
{
    int vector[size];
    vector_t v, *pV;
    pV = &v;
    pV->size = size;
    pV->vector = vector;
    return pV;
}

int main(int argc, char* argv[])
{
    vector_t* vec = vector_new(3);
    printf("v has size %d.\n", vec->size);
    printf("v has size %d.\n", vec->size);
    getchar();

    return EXIT_SUCCESS;
}  

它构建并运行,但由于函数vector_new中该变量的局部范围,因此返回main()中vec-&gt;大小的非预期值。

建议创建结构的全局可见实例,并将vector_new()重新定义为int initVector(void)

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

#define SIZE 10

typedef struct
{
    size_t size;
    int* vector;
} vector_t;
vector_t v, *pV;//globally visible instance of struct

int initVector(void)
{
    int i;
    pV->size = SIZE;
    pV->vector = calloc(SIZE, sizeof(int));
    if(!pV->vector) return -1;
    for(i=0;i<SIZE;i++)
    {
        pV->vector[i] = i; 
    }
    return 0;
}

int main(int argc, char* argv[])
{
    int i;
    pV = &v; //initialize instance of struct
    if(initVector() == 0)
    {
        printf("pV->size has size %d.\n", pV->size);
        for(i=0;i<SIZE;i++) printf("pV->vector[%d] == %d.\n", i, pV->vector[i]);
    }
    getchar(); //to pause execution

    return EXIT_SUCCESS;
}  

产生这些结果:

enter image description here

您仍然需要编写一个freeVector函数来撤消所有已分配的内存。