指向结构的指针在C中返回不正确的值

时间:2016-03-10 07:42:42

标签: c pointers struct typedef

我已经创建了一个C结构类型:

typedef struct {
  int* data;
  unsigned int len;
} intarr_t;

我正在尝试从指向我(显然)成功创建的intarr_t对象的指针中访问len。以下是我在这里工作的两个文件......

intarr.h

/* Structure type that encapsulates our safe int array. */
typedef struct {
  int* data;
  unsigned int len;
} intarr_t;

/* A type for returning status codes */
typedef enum {
  INTARR_OK,
  INTARR_BADARRAY,
  INTARR_BADINDEX,
  INTARR_BADALLOC,
  INTARR_NOTFOUND
} intarr_result_t;


// Create a new intarr_t with initial size len.  If successful
// (i.e. memory allocation succeeds), returns a pointer to a
// newly-allocated intarr_t.  If unsuccessful, returns a null pointer.
intarr_t* intarr_create( unsigned int len );

// If index is valid, set the value at ia->data[index] to val and return
// INTARR_OK. Otherwise, leave the array unmodified and return
// INTARR_BADINDEX. If ia is null, return INTARR_BADARRAY.
intarr_result_t intarr_set( intarr_t* ia, 
                unsigned int index, 
                int val );

intarr.c

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

intarr_t* intarr_create( unsigned int len ) {

    intarr_t original;
    original.len = len;
    original.data = malloc(original.len * sizeof(int));

    //populate with values
    for (int i = 0; i < original.len; i++) {
        original.data[i] = i;
    }

    if (original.data == 0) {
        intarr_t* originalp = NULL;
        return originalp;
    }

    else {
        intarr_t* originalp = &original;
        return originalp;
    }
}

intarr_result_t intarr_set( intarr_t* ia, 
                unsigned int index, 
                int val ) {

    if (ia == NULL) {
        printf("%s\n", "error: array is null");
        return INTARR_BADARRAY;
    }

    else if (index) { //need to check bounds properly here with ia->len, but it won't work
        ia->data[index] = val;
        //printf("length of array: %d\n", ia->len);
        return INTARR_OK;
    }

    return INTARR_BADINDEX;
}



int main() {
    intarr_t* arr = intarr_create(11);
    intarr_t* arra = NULL;
    intarr_set(arr, 80, 420);
    return 0;
}

要检查intarr_set()中的索引边界,我想查看索引的值,看它是否介于0和ia->len之间。但是,ia->len返回420而不是11,主要指定。由于ia->len生成了一个指向intarr_create()original为11的intarr_t对象,因此len的值为{11}?为什么是这样? val不属于intarr_t结构。它只是一个参数。我试图在主要的len arr上进行操作。

目前我已编写if (index)只是为了让程序正确编译,直到调试完毕。

index中的

intarr_set()会返回正确的值。

val中的

intarr_set()会返回正确的值。

len中的

intarr_create()会返回正确的值。

即使dataoriginaloriginalp中的arr包含正确的值。

ia->len不会返回正确的值。

为什么?

有人可以告诉我,我在这里失踪了吗?感谢。

1 个答案:

答案 0 :(得分:2)

问题在于:

intarr_t original;
...
intarr_t* originalp = &original;
return originalp;

返回指向局部变量的指针。局部变量超出范围,一旦它们被定义的函数返回就不再存在。

如果你想真正创建一个结构实例,你应该动态分配它(例如malloc)。