2014-10-08 92 views
0

我完全準備好被告知我正在做一些愚蠢/錯誤的事情;這是我所期望的。指向結構,字段莫名其妙地改變值

當我從指針訪問字段時,我感覺到了結構,並且出現了一個裁剪器。要遵循的代碼。

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。到底是怎麼回事?

在此先感謝。

+0

我建議改爲設計它,首先創建並分配結構,然後將指針傳遞給一個init函數,該函數接受所創建結構的指針,並將其作爲void(修改指向結構的成員通過指針而不是嘗試在函數中創建結構)。 – 2014-10-08 17:38:20

+0

新的功能太痛苦了...最糟糕的做法,它甚至不可維護。您應該改爲使用malloc。你的問題是由堆棧造成的。您返回的地址在堆棧中,但是,這部分堆棧由'printf'使用,即您的數據已損壞。 – HuStmpHrrr 2014-10-08 17:57:03

回答

1

您正在從vector_new返回一個指向局部變量v的指針。這沒有絲毫的工作機會。到vector_new返回到main時,所有局部變量都被銷燬,指針指向任何地方。而且,內存v.vector指向的也是本地數組vector。當vector_new返回時它也被銷燬。

這就是爲什麼你看到你的printf打印垃圾。

您的代碼必須完全重新設計內存管理。實際的數組必須動態分配,使用mallocvector_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函數。

+0

非常感謝。這基本上是我編寫我所有功能所需要知道的。 – 2014-10-09 19:18:06

0

完全重新編寫的答案來解決你的問題,並提供替代方法:& v是非法的返回值:

寫在OP不會編譯代碼。

如果我修改代碼這樣:

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

它建立和運行,但對於vec-返回意外值>尺寸main()由於該變量在vector_new該函數的局部範圍。

推薦創建結構的全局可見實例,並重新定義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功能取消所有分配的內存。

+0

'malloc(10)'是壞的,即使是一個演示... – HuStmpHrrr 2014-10-08 17:58:15

+0

@HuStmpHrrr - :),是的,它是。 – ryyker 2014-10-08 18:02:58

相關問題