2015-06-01 118 views
0

我正在嘗試使用一個結構「學生」和另一個結構「堆棧」來製作一個小鏈表,該結構包含學生結構和指向下一個元素的指針。訪問衝突寫入位置0xCDCDCDCD

但是我不斷地收到一個存儲器訪問錯誤。我雙檢查,以確保所有的指針被初始化(只有一個指針,Stacktop,初始化爲NULL)

這裏有結構定義:

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

using namespace std; 

struct students 
{ 
    int matnr; 
    string name; 
}; 

struct stack 
{ 
    students stud; 
    stack *next; 
}; 

typedef struct stack Stack; 
typedef Stack *ptrStack; 

void push(students s); 
students pop(); 
int isEmpty(); 
void printStack(students stud); 

這裏是推送功能(這使崩潰的PROGRAMM)

#include "stack.h" 

ptrStack Stacktop = NULL; 

void push(students s) 
{ 
    ptrStack stack = (ptrStack)malloc(sizeof(Stack)); 

    if (stack == NULL) 
    { 
     cout << "!!FIN!!" << endl; 
     return; 
    } 

    stack->stud = s; 
    stack->next = Stacktop; 
    Stacktop = stack; 

    return; 
} 

這裏是主要的:

#include "stack.h" 

students readStuds() 
{ 
    students s; 

    cout << "Enter Student name: " << endl; 
    cin >> s.name; 
    cout << "Enter Matr Nr: " << endl; 
    cin >> s.matnr; 

    return s; 
} 

int main() 
{ 

char c; 

do { 
     push(readStuds()); 

     cout << "Continue Entering Students? " << endl; 
     cin >> c; 
     cout << "----------------------" << endl; 
     cout << "----------------------" << endl; 
} while (c != 'q'); 

cout << " POPPING STACK " << endl; 
cout << " ............. " << endl; 

while (isEmpty()) 
{ 
    printStack(pop()); 
} 

}

+2

不要在C++中使用malloc – Borgleader

+0

您正在通過malloc或new使用已分配的內存,但從未由應用程序編寫[何時以及爲什麼OS將內存初始化爲0xCD ,0xDD等malloc/free/new/delete?](http://stackoverflow.com/q/370195/995714) –

+0

C語言不包含'cin'或'cout',所以你的C標籤是不適當。即使它們有相似之處,它們也不是*相同的語言。請僅使用與您要問的問題實際相關的標籤;否則會破壞標籤系統的用途。謝謝。 –

回答

5

這結束:

ptrStack stack = (ptrStack)malloc(sizeof(Stack)); 

分配足夠的內存來容納struct stack a.k.a Stack,但malloc()沒有做任何事情來初始化返回的內存。因此,特別是,您的新stack中的string包含隨機垃圾,該垃圾將被您的cin >> s.name解釋,並被假定爲有效的string,事實並非如此,因此代碼失敗。

解決方法 - 使用ptrStack stack = new Stack代替。更妙的是,寫正確的構造函數/析構函數,拷貝構造函數,賦值運算符等......

+0

tyvm ^^我承認我混合了一點C和C++,謝謝你的幫助,我剛剛在2分鐘內解決了一個問題,一直工作了2個小時!我完全忘記了在創建階段需要自己的構造函數的字符串。 –

1

你這樣做:

ptrStack stack = (ptrStack)malloc(sizeof(Stack)); 
             ^^^^^ 

其定義爲:

typedef Stack *ptrStack; 

因此,sizeof(Stack)基本上是size(pointer)。你沒有爲你的結構分配足夠的內存,你爲POINTER分配足夠的內存給你的結構。所以,是的,你運行了你分配的內存

+0

typedef struct stack Stack; <<堆棧看起來不錯? – willll

+0

該行'typedefs''ptrStack'。上面定義的'Stack'不是'struct stack',它的定義是否正確? – Persixty

+1

這就是爲什麼'new'比'malloc'更安全的原因:你不能得到錯誤的內存量,因爲它是自動計算的。它看起來也很漂亮。 – edmz

3

的問題是,你混合C和C++,特別是在這行代碼

ptrStack stack = (ptrStack)malloc(sizeof(Stack)); 

Stack結構包含類型爲string的對象。 string構造函數必須調用,然後才能使用string。如果使用C++ new運算符分配內存,則自動調用構造函數,並且string已正確初始化。

但是,如果你使用的是C malloc功能分配內存,那麼string構造是調用。 0xCDCDCDCD來自應該由構造函數初始化的字符串對象中的未初始化指針(但不是因爲未調用構造函數)。

故事的寓意:不要混用C和C++,除非你在兩者中都有很多經驗。

+0

非常感謝你^^解釋未初始化的指針問題:) 是啊,很多人說C/C++是相同的,但有一些激烈的差異 –

+0

不客氣,很高興我可以幫助:) – user3386109