2016-06-26 28 views
-3

整數時,這是我的代碼,Tuple.c,它在該行產生段錯誤有評論這樣說:段錯誤提領從虛空PTR

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

void dbwait(); 

typedef struct STuple { 
    int tSize; 
    void** values; 
} Tuple; 

Tuple* CreateTuple(int n_args, ...) { 
    va_list varlist; 
    va_start(varlist, n_args); 

    int varsSize; 
    void** vars = (void**)malloc(n_args * sizeof(void*)); 

    for (int i = 0; i < n_args; i++) { 
     void* arg = va_arg(varlist, void*); 
     varsSize += sizeof(arg); 
     vars[i] = arg; 
     printf("Arg ptr = %p\n", arg); 
    } 

    // Size of all of the arguments + size of an int value (varsSize) since Tuple has an array of void* and a single int. 
    Tuple* t = (Tuple*)malloc(varsSize + sizeof(varsSize)); 

    t->values = vars; 
    t->tSize = n_args; 

    va_end(varlist); 

    return t; 
} 

void FreeTuple(Tuple* t) { 
    printf("Freeing tuple at %p\n", (void*)t); 
    free(t->values); 
    free(t); 
} 

int main(int argc, char** argv) { 
    Tuple* rt = CreateTuple(3, 625, 173, 50); 

    int length = rt->tSize; 

    printf("%i\n", length); // Prints 3, as defined in the call to CreateTuple 
    dbwait(); 

    for (int i = 0; i < length; i++) { 

     printf("index = %i: ", i); 
     dbwait(); 

     void* ptr = rt->values[i]; 
     printf("At ptr %p, ", ptr); dbwait(); 

     int value = *((int*)ptr); // SegFault Occurs here! 
     printf("with value = %d\n", value); 
     dbwait(); 
    } 

    dbwait(); 

    FreeTuple(rt); 

    return 0; 
} 

void dbwait() { 
    char* stop = (char*)malloc(sizeof(char)); 
    scanf("%c", stop); 
    free(stop); 
} 

我知道一個事實,即地址分配給ptrptr = rt->values[i];是正確的,因爲每當我複製該地址作爲其從gdb打印並打印(地址),它打印出正確的值625.

爲什麼我會得到一個SegFault時,地址正確指向一個整數?

編輯:我已經根據其他用戶的要求,用我上面顯示的整個tuple.c文件替換了我的問題的當前代碼內容。

+2

請發表[mcve]。你認爲調用'malloc'的結果是什麼,然後立即覆蓋它在下一行返回的結果?這不是使用'malloc'的正確方法,如果你認爲這是正確的,那麼建議你再次挖掘你的fav C文本。 – kaylum

+0

你介意爲CreateTuple提供代碼嗎?我認爲問題在於它,因爲在你的例子中'malloc'和變量是過度的並且什麼都不做,所以整個例子可以縮寫爲*((int *))CreateTuple(3,625,173,50) - >值[I])'。 – yeputons

+1

你說「我知道所有這些malloc都是過度的」。事實上,他們模糊了你的榜樣。 – jdigital

回答

2

如果*ptr是625,那麼*valPtr被提領該地址625

如果運行這個調試器裏面,看看在你解引用它的時候valPtr的價值。

+0

我用我正在調試的實際代碼編輯了我的問題。 – TristenHorton

+0

你實際上可能會帶領我走向正確的方向。看起來像0x271實際上是625的小數點,所以顯然我需要創建一個int *,malloc,並將值賦給va_list。 謝謝你給我一些很好的建議。 – TristenHorton

+0

引導我走向正確的方向。我的Tuple代碼實際上工作正常,但在調用CreateTuple時,我應該傳遞指向值而不是值的指針。我通過CreateTuple傳遞指針,現在它可以工作!非常感謝jdigital。 – TristenHorton

0

您mallocs的所有正在泄漏內存,因爲你在寫mallocs在下一行返回:

void* ptr = malloc(sizeof(rt->values[i])); 
ptr = rt->values[i]; // You've now lost the pointer to malloced memory. 

看起來你想要的東西,像*ptr = ...把東西放到新創建的塊。在intPtr的情況下,您將其值設置爲int,然後再次嘗試將其用作指針。由於它不可能是一個有效的地址,你會得到一個段錯誤。

+0

我有一個說明,說我的malloc過度了,我知道他們在泄漏內存。在發佈答案之前,請閱讀完整的問題。我使用導致段錯誤的整個實際代碼文件編輯了我的問題。 **編輯:**它看起來像@jdigital可能會帶領我在正確的方向。儘快更新。 – TristenHorton