2

I am to make a linked list in C with an ordered insert function. The array lists is an array of individual linked lists and I have to generate 10000 random numbers and sometimes I can generate 300 or 400 numbers and sometimes it fails and gives me a buffer overrun exception. What is the reason for me getting this?

I thought it might be because I need to free some memory but it seems to me that I need all the memory I am allocating, nothing is left over.

When the error occurs the call stack shows this line:

struct Node *newNode = (struct Node *)malloc(sizeof(*newNode));

is what is causing the exception.

It works properly with less numbers being generated, like if I do 100 numbers the output looks like this: http://gyazo.com/18a9ba87611f5676d6fa7b6229fc41e0 That's not the full output of course but that's the idea.

// Program 6.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <time.h>
#include <stdlib.h>


#define MAX 200

void orderedInsert(struct Node **, int);
void printList(struct Node **, int);


struct List{
    int size;
    struct Node *front;
};

struct Node{
    int value;
    struct Node *next;
};

void main(){

struct List lists[MAX];
int i, random;

for(i = 0; i < MAX; i++){
    lists[i].front = 0;
    lists[i].size = 0;
}
srand(time(NULL));

for(i = 0; i < 100; i++){
    random = rand() % 10000000;
    orderedInsert( &(lists[random%MAX].front), random);
    (lists[i].size)++;
}

for(i = 0; i < MAX; i++){
    printf("%d ", i);
    printList( &(lists[i].front), lists[i].size);
}


scanf_s("%d", NULL);

}


void orderedInsert(struct Node **front, int value){

struct Node *newNode = (struct Node *)malloc(sizeof(*newNode));
struct Node *temp, 
            *prev;

newNode->value = value;


if(*front == NULL){
    *front = newNode;
    newNode->next = 0;
    return;
}

if((*front)->value > newNode->value){
    newNode->next = *front;
    *front = newNode;
    return;
}
temp = (*front)->next;
prev = *front;

while(temp != NULL && temp->value < newNode->value){
    prev = temp;
    temp = temp->next;
}
newNode->next = temp;
prev->next = newNode;

}

void printList(struct Node **front, int value){

struct Node *temp;
temp = *front;

if(temp){
    printf("The list contains elements: %d", temp->value);
    temp = temp->next;

    while(temp != NULL){
        printf(", %d", temp->value);
        temp = temp->next;
    }

    }
    printf("\n");

}

Here is the full call stack if you need it-

    msvcr110d.dll!_crt_debugger_hook(int _Reserved) Line 57 C
    Program 6.exe!__raise_securityfailure(_EXCEPTION_POINTERS * ExceptionPointers) Line 67  C
    Program 6.exe!__report_gsfailure() Line 235 C
    msvcr110d.dll!ValidateLocalCookies(void (unsigned int) * CookieCheckFunction, _EH4_SCOPETABLE * ScopeTable, char * FramePointer) Line 198   C
    msvcr110d.dll!_except_handler4_common(unsigned int * CookiePointer, void (unsigned int) * CookieCheckFunction, _EXCEPTION_RECORD * ExceptionRecord, _EXCEPTION_REGISTRATION_RECORD * EstablisherFrame, _CONTEXT * ContextRecord, void * DispatcherContext) Line 329 C
    Program 6.exe!_except_handler4(_EXCEPTION_RECORD * ExceptionRecord,          _EXCEPTION_REGISTRATION_RECORD * EstablisherFrame, _CONTEXT * ContextRecord, void * DispatcherContext) Line 94 C
    ntdll.dll!77e2b499()    Unknown
    [Frames below may be incorrect and/or missing, no symbols loaded for        ntdll.dll]  
    ntdll.dll!77e2b46b()    Unknown
    ntdll.dll!77e2b40e()    Unknown
    ntdll.dll!77de0133()    Unknown
    msvcr110d.dll!malloc(unsigned int nSize) Line 56    C++
>   Program 6.exe!orderedInsert(Node * * front, int value) Line 59  C
    Program 6.exe!main(...) Line 42 C
    Program 6.exe!__tmainCRTStartup() Line 536  C
    cd001c1d()  Unknown

I got another error: Unhandled exception at 0x100B26B6 (msvcr110d.dll) in Program 6.exe: 0xC0000005: Access violation reading location 0x0146F78F.

Call stack for this one:

>   msvcr110d.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int      nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 239 C++
    Program 6.exe!orderedInsert(Node * * front, int value) Line 59  C
    Program 6.exe!main(...) Line 42 C
    Program 6.exe!__tmainCRTStartup() Line 536  C
    a500201d()  Unknown

This isn't the full call stack. The full call stack is miles long.

Sam Burns
  • 103
  • 12
  • 2
    `(struct Node *)malloc(sizeof(*newNode))` should be `malloc(sizeof(struct Node))` – SleuthEye Apr 25 '15 at 20:10
  • I get a syntax error if I do that. "Error: a value of type "void *" cannot be used to initialize an entity of type "Node *" – Sam Burns Apr 25 '15 at 20:12
  • 1
    @SamBurns You're compiling this as a C source file with Visual Studio, I assume. – WhozCraig Apr 25 '15 at 20:14
  • Yes, we are not allowed to use C++ – Sam Burns Apr 25 '15 at 20:15
  • The VS compiler, even in C-mode, will whine about `malloc` assignments directly to typed pointers like yours. Normally it is a bad idea to cast `malloc`, You're obviously including the right stuff to get the proper prototype for `malloc`, otherwise you would have received two warnings/errors (one for an implicit declaration of `malloc`, the other for trying to assign `int` to a pointer). Regardless, check your compiler switches and make *sure* your compiling as C code for your `.c` file. If you are, intellisense will still bitch, but it should only emit a warning at compile-time. – WhozCraig Apr 25 '15 at 20:19
  • I changed it by going to project properties > Configuration Properties > C/C++ > Advanced > Compile As > "Compile as C Code (/TC)" Is that the proper way? – Sam Burns Apr 25 '15 at 20:21
  • Sounds like you did it right. And to your *real* problem, somewhere in your code you're likely corrupting the heap and the side effect(s) of that undefined behavior invocation is rearing in this `malloc` when heap chain is detected as bad. Not much help, but that is where this will eventually lead. – WhozCraig Apr 25 '15 at 20:22
  • I guess it's unrelated but near the end main reads `scanf_s("%d", NULL);` : what's that? why NULL? – Diego Apr 25 '15 at 20:25
  • Just to pause the program so I can look at the output. – Sam Burns Apr 25 '15 at 20:25
  • yea, but the function will store the value read at NULL which is wrong – Diego Apr 25 '15 at 20:26
  • I don't ever even enter anything in, but I have since changed it to i just to be sure. It doesn't do anything different. – Sam Burns Apr 25 '15 at 20:30
  • You have a possible corruption in the printing function. Note, you're incrementing the i-th list size and not the one to which you actually insert. This will surely lead to corruption later when printing. – SomeWittyUsername Apr 25 '15 at 20:31
  • That was the problem, I had not realized. Thank you, put it in an answer so I can accept it. – Sam Burns Apr 25 '15 at 20:33

1 Answers1

1

You have a possible corruption in the printing function. Note, you're incrementing the i-th list size and not the one to which you actually insert. This will surely lead to corruption later when printing. Still it's a bit weird that your failure occurs before getting to the print itself.

SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85
  • 1
    For future readers I think it would help to put that I changed (lists[i].size)++; to (lists[random%MAX].size)++; – Sam Burns Apr 25 '15 at 20:35