0

I am trying to make a small linked list using one structure "students" and another sturcture "stack", which holds the student structure and the pointer to the next element.

However i constantly keep getting a memmory access error. I double checked to make sure all pointers are initialized (only one pointer, Stacktop, initialized to NULL)

Here are the structure definitions:

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

Here is the push function (which keeps crashing the 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; 
}

And here is the main:

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

}

Ken White
  • 123,280
  • 14
  • 225
  • 444
Emir Masic
  • 184
  • 1
  • 2
  • 8
  • 2
    Don't use malloc in C++ (unless you *absolutely* know what youre doing) – Borgleader Jun 01 '15 at 17:23
  • You're using an allocated memory via malloc or new but never written by the application [When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?](http://stackoverflow.com/q/370195/995714) – phuclv Jun 01 '15 at 17:27
  • The C language does not contain `cin` or `cout`, so your C tag is not appropriate. They are *not* the same language, even though they have similarities. Please use only the tags that are actually relevant to the question you're asking; doing otherwise defeats the purpose of the tag system. Thanks. – Ken White Jun 01 '15 at 17:57

3 Answers3

5

This:

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

allocates enough memory to hold a struct stack a.k.a Stack, but malloc() does not do anything to initialize the memory that is returned. So, in particular, the string inside your new stack contains random garbage, which will then be interpreted by your cin >> s.name, and assumed to be a valid string, which it isn't, so the code fails.

Solution - use ptrStack stack = new Stack instead. Even better, write proper constructors/destructors, copy constructors, assignment operators, etc...

twalberg
  • 59,951
  • 11
  • 89
  • 84
  • tyvm ^^ I admit i mixed a little too much C and C++, thanks to your help i just solved a problem in 2 minutes that ive been working on for 2 hours !! I completely forgot about string needing its own constructor that MUST be called during creation phase. – Emir Masic Jun 01 '15 at 18:16
3

The problem is that you're mixing C and C++, specifically in this line of code

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

The Stack structure contains an object of type string. The string constructor must be called before you can use the string. If you allocate memory using the C++ new operator, then the constructor is automatically called, and the string is properly initialized.

But if you allocate memory using the C malloc function, then the string constructor is not called. The 0xCDCDCDCD comes from an uninitialized pointer in the string object that should have been initialized by the constructor (but wasn't because the constructor was not called).

The moral of the story: don't mix C and C++ until you have a lot of experience in both.

user3386109
  • 34,287
  • 7
  • 49
  • 68
  • Ahh thank you very much ^^ that explains the uninitialized pointer problem :) Yea, alot of people say C/C++ are the same, but there are some drastic differences – Emir Masic Jun 01 '15 at 17:59
1

You're doing:

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

which is defined as:

typedef Stack *ptrStack;

therefore, sizeof(Stack) is essentially size(pointer). You're not allocating enough memory for your structure, you're allocating enough memory for a POINTER to your struct. So yes, you are running off the end of your allocated memory

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • That line 'typedefs' `ptrStack`. Isn't `Stack` defined above as `struct stack` which is defined correctly? – Persixty Jun 01 '15 at 17:26
  • 1
    That's why `new` is so much safer than `malloc`: you can't get the amount of memory wrong because it's automatically calculated. It looks nicer, too. – edmz Jun 01 '15 at 17:26
  • or just `sizeof(stack)`. C/C++ are case sensitive. `stack != Stack`. – Marc B Jun 01 '15 at 17:27