-4

I have this function in c++ that should add a member to a linked list, but when it's executed it throw an exception:

Unhandled exception at 0x5b9414cf (msvcr100d.dll) in Sample.exe: 0xC0000005: Access violation reading location 0x00000001

This happen when some variable isn't definite...but I can't figure out where is this variable...also with breakpoints. Here the entire code (except for the .h file...but it only contains declaration)

#include "stdafx.h"
#include "winsock.h"
#include "windows.h"
#include <string.h>
#include <iostream>
#include "Sample.h"

using namespace std;

struct BUNNY 
{
public:
    int sex;
    int name;
    int age;
    bool colour;
    int radioactive_mutant_vampire_bunny;

    BUNNY *nextBunny;
};


int returnSex();
int returnName (int sex); 
int returnColour ();
bool radioactiveBunny ();

string translateName(int name);
string translateSex(int sex);
string translateColour(int colour);

BUNNY * AddBunny(BUNNY * head,int sex,int name,int colour,bool radioactive_mutant_vampire_bunny);
BUNNY * travereseBunny(BUNNY * head);
BUNNY * displayBunny();

int _tmain(int argc, _TCHAR* argv[])
{
    bool flag = true;
    int turn = 0;
    BUNNY * head = new BUNNY;
    head = NULL;

    while (flag)
    {
        ++turn;
        if (turn == 1)
        {
            for (int i = 1; i <= 5; i++)
            {
                int sex = returnSex();
                int name = returnName(sex);
                int colour = returnColour();
                bool radioactive = radioactiveBunny();
                head = AddBunny(head,sex,name,colour,radioactive);
                printf("A new bunny is born: sex %s , name %s , colour %s , radioactive %d",head->sex,head->name,head->colour,head->radioactive_mutant_vampire_bunny);

                system("pause");
            }


        }
    }

return 0;
}

int returnSex()
{
    int random = rand() % 100 + 1;
    if(random > 50)
        return MALE;
    else
        return FEMALE;
}

int returnName(int sex)
{

    if (sex == MALE)
    {
        int random = (rand() % 100 + 1) / 5;
        if(random < 20)
            return BU;
        else if (random > 20 && random <40)
            return CRYSTAL;
        else if(random > 40 && random < 60)
            return JASON;
        else if(random > 60 && random < 80)
            return ERO;
        else if(random > 80)
            return METH;
    }
    else 
    {
        int random1 = rand() % 100 + 1;
        if (random1 < 50 )
        {
            return MARIA;
        }
        else if (random1 > 50)
            return JAMIE;
    }
}

int returnColour ()
{
    int random = rand() % 4 + 1;
    if(random == 1)
        return WHITE;
    else if(random > 1 && random <= 2)
        return BROWN;
    else if(random > 2 && random <= 3)
        return BLACK;
    else if(random > 3 && random <= 4)
        return SPOTTED;
}

bool radioactiveBunny()
{
    int random = rand() % 100 + 1;
    if(random > 0 && random <= 2)
        return true;
    else 
        return false;
}

BUNNY * AddBunny(BUNNY * head,int sex,int name,int colour,bool radioactive_mutant_vampire_bunny)
{
    BUNNY * newBunny = new BUNNY;
    newBunny->age = 0;
    newBunny->colour = colour;
    newBunny->sex = sex;
    newBunny->name = name;
    newBunny->radioactive_mutant_vampire_bunny = radioactive_mutant_vampire_bunny;

    newBunny->nextBunny = head;
    return newBunny;
}

string translateName (int name)
{
    switch (name)
    {
    case CRYSTAL: return "CRYSTAL";
        break;
    case BU: return "BU";
        break;
    case JASON: return "JASON";
        break;
    case ERO: return "ERO";
        break;
    case METH: return "METH";
        break;
    case MARIA: return "MARIA";
        break;
    case JAMIE: return "JAMIE";
        break;
    }
}

string translateColour (int colour)
{
    switch (colour)
    {
    case WHITE: return "WHITE";
        break;
    case BLACK: return "BLACK";
        break;
    case BROWN: return "BROWN";
        break;
    case SPOTTED: return "SPOTTED";
        break;
    }
}

string translateSex (int sex)
{
    switch (sex)
    {
    case MALE: return "MALE";
        break;
    case FEMALE: return "FEMALE";
        break;
    }
}

this is the entire code...hope it will help. thanks for your time :)

Azazel
  • 25
  • 1
  • 6
  • Whats about giving us the line? – Sebastian Hoffmann Mar 05 '14 at 15:58
  • Can you show us BUNNY? – Stefan Neubert Mar 05 '14 at 15:58
  • 3
    I'm almost sure that the bug isn't in the code snippet you provided but we must see the declaration of `BUNNY` for this. – pasztorpisti Mar 05 '14 at 16:00
  • can you print the address of `BUNNY* head`? I'm not sure of the best way to do it in correct C++, but in C it'd be `printf("%X", head);` – zmo Mar 05 '14 at 16:00
  • If its really this method, than the only thing which could fail is the default constructor – Sebastian Hoffmann Mar 05 '14 at 16:01
  • @zmo `head` is never dereferenced, besides that, the print would also result in a crash, therefor we use debuggers. – Sebastian Hoffmann Mar 05 '14 at 16:02
  • (I removed my comment because I figured my mistake out), and @Paranaix I'm assuming the same thing as you do: the error is not in that function, but I think it is either `head` pointing to nothing and being dereferenced elsewhere, or default constructor failing. That's why I'm asking for the address of head, to weed out that possibility. – zmo Mar 05 '14 at 16:03
  • @zmo FYI `BUNNY foo = Bunny();` wont invoke `operator=()` too, as assignemnt when initializing is translated to a regular constructor call. So only `Bunny()` would be invoked, no copy constructor, no copy assignment operator. – Sebastian Hoffmann Mar 05 '14 at 16:06
  • Not a big issue, but you've got `radioactive_mutant_vampire_bunny` as `int` in the structure declaration, and as `bool` everywhere else. – Joe M Mar 05 '14 at 16:10
  • if you missed it in my former comment: *I removed my comment because I figured my mistake out* ;-) – zmo Mar 05 '14 at 16:10
  • @zmo yeah yeah, that was just an addition to my previous comment – Sebastian Hoffmann Mar 05 '14 at 16:12

2 Answers2

1

Whether there is a probelm or no depends on how you call the function

It should be called the following way

head = AddBunny( /* some arguments */ );

If you call it such a way then there is no problem with the function.

If you call it as for example

AddBunny( /* some arguments */ );

that is without assigning head by the returning pointer then head will be always equal to NULL.

EDIT: After you showed additional code then I would like to point out that these statements

BUNNY * head = new BUNNY;
head = NULL;

are invalid. There is a memory leak. You at first allocate memory and head gets the address of the memory and then you reassign the head.

There must be

BUNNY * head = NULL;

Also it seems your code has a typo. You defined private data members as

bool colour;
int radioactive_mutant_vampire_bunny;

but corresponding parameters of function AddBunny are defined diffirently

BUNNY * AddBunny(BUNNY * head,int sex,int name,int colour,bool radioactive_mutant_vampire_bunny);

The abend was due to incorrect formating symbol. You defined colour as bool but trying to output it as a string literal.

printf("A new bunny is born: sex %s , name %s , colour %s , radioactive %d",head->sex,head->name,head->colour,head->radioactive_mutant_vampire_bunny);

You wrote colour %s while head->colour has type bool

By the way the address 0x00000001 shown in the message

Access violation reading location 0x00000001 

is the value of colour that is equal to boolean literal true that is to 1.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Maybe my vision is bad, but I read: `head = AddBunny(head,sex,name,colour,radioactive);` – Sebastian Hoffmann Mar 05 '14 at 16:13
  • could you remove the first part of your post that's *really* not relevant anymore given the edit? – zmo Mar 05 '14 at 16:14
  • @Paranaix The original post was changed. I understand that this idea could not came to your head. – Vlad from Moscow Mar 05 '14 at 16:14
  • @VladfromMoscow I dont get your objection. But your first part became irrelevant, as soon as he posted his calling code. And while your mention of the memory leak is right, this does however not cause an access violation. – Sebastian Hoffmann Mar 05 '14 at 16:18
  • @Paranaix I am not going to follow a silly advice because the original post can be changed in any moment. It is not my problem. And moreover the first part is relevant. – Vlad from Moscow Mar 05 '14 at 16:27
  • @VladfromMoscow Geez, whats your problem? You now have a whole bunch of text while the actual solution to the problem is appearing right at end. The first part stays irrelevant because the OP does not call it this way. Why dont you write an essay about flowers here? There are endless things that can happen, which could be improved or which could be different. But thats not asked. – Sebastian Hoffmann Mar 05 '14 at 16:31
  • @Paranaix It would be better if you would delete your post because you simply copied after me what I wrote. – Vlad from Moscow Mar 05 '14 at 16:33
  • @VladfromMoscow Lol ofc, just go to hell – Sebastian Hoffmann Mar 05 '14 at 16:34
-2

Your problem is the printf statement, consider the following:

printf("Test: %s", 2);

This will produce a crash, as printf is assuming a string, but you pass an integer. The integer will thus be interpreted as char* and therefor result in an access violation as soon as printf tries to print any char (which requires dereferencing the pointer).

But this is exactly what happens if you do:

printf("A new bunny is born: sex %s", head->sex);

As BUNNY::sex is declared as int.

Joe M
  • 3,060
  • 3
  • 40
  • 63
Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77