Thread: very strange memory problem

  1. #1
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466

    very strange memory problem

    Here's a question for you pros:

    I am making a array ADT type that dynamically resizes itself when you attempt to access elements that would normally be out-of-bounds. I have initialized the struct to size 0 and allocated enough memory for 16 integers in another function that I have already debugged and called.

    array.c
    Code:
    struct arrayADT
    {
        unsigned int size;
        unsigned int capacity;
        int *data;
    };
    
    void ArrayADT_setElement(struct ArrayADT *array, const unsigned index, const int newValue)
    {
        struct arrayADT *p = (struct arrayADT *)array;
        if (index >= p->size)
        {
        	ArrayADT_resize(array, index);
        }
    	p->data[index] = newValue;
    }
    
    void ArrayADT_resize(struct ArrayADT *array, const unsigned newsize)
    {
        struct arrayADT *p = (struct arrayADT *)array;
    
        if (newsize <= 16)
        {
        	p->capacity = 16;
        }
        else if (newsize < p->capacity)
        {
    	    while ((p->capacity >> 1) >= newsize)
    	    {
    	        p->capacity = p->capacity >> 1; // divide by 2
    	    }
        }
        else
        {
            while (p->capacity < newsize)
            { 
                p->capacity = p->capacity << 1; // mult by 2
            }
        }
        p->size = newsize + 1;
        if (!realloc(p->data, sizeof(int) * p->capacity))
    	{
    		printf("Memory allocation error.\n");
    		exit(1);
    	}
    }
    I am having a very strange memory problem. I have spent all morning running this program through the debugger and have narrowed the problem down to this line

    p->data[index] = newValue;

    which causes an memory access violation exception. Also if I create a large sized array, say 4000 ints, when I try to free the memory I get a possible heap corruption exception...

    In Linux I don't get a exception but my array size and capacity become junk values.

    Any help is appreciated I am stuck here...
    Last edited by MacNilly; 09-12-2006 at 03:15 PM.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    My first reaction is to ask you why that functionality is beneficial to begin with. My second reaction is to tell you to simplify. You're falling into the trap of premature optimization, and it could very likely be causing your problem.
    My best code is written with the delete key.

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    You're using realloc() incorrectly. realloc() returns a pointer to the new memory location. Sometimes (not always, but sometimes) realloc() has to move your data to a different location to make everything fit and you're ignoring that return value so your data member ends up pointing to invalid memory.

    I'd recommend rewriting this:
    Code:
        if (!realloc(p->data, sizeof(int) * p->capacity))
    	{
    		printf("Memory allocation error.\n");
    		exit(1);
    	}
    as...:
    Code:
        if (!(tmp = realloc(p->data, sizeof(int) * p->capacity)))
    	{
    		printf("Memory allocation error.\n");
    		exit(1);
    	}
        p->data = tmp;
    The reason for the tmp variable is if realloc() fails you still end up with a pointer to the data so you can do what you need to with it on failure instead of just scattering it into the wind.
    If you understand what you're doing, you're not learning anything.

  4. #4
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466

    Thanks

    Man I'm still a N00b when it comes to C programming. I just finished a course in C++ so I haven't used realloc() in years.
    Actually I just found the problem but thank you for the quick reponse itsme86 that was exactly the problem.
    As for the premature optimiziation, I don't know....

  5. #5
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Quote Originally Posted by Prelude
    My first reaction is to ask you why that functionality is beneficial to begin with. My second reaction is to tell you to simplify. You're falling into the trap of premature optimization, and it could very likely be causing your problem.
    The reason for the capacity being a multiple of 2 is to prevent memory fragmentation that occurs if odd-sized blocks of memory are allocated many times over.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >The reason for the capacity being a multiple of 2 is to prevent memory
    >fragmentation that occurs if odd-sized blocks of memory are allocated many times over.
    Okay, but that still doesn't answer why you allow any index by resizing the array. What happens if I accidentally say:
    Code:
    ArrayADT_setElement ( array, -1, my_val )
    This is a legitimate error, but your code will attempt to satisfy the request (with disatrous results) instead of going ballistic as it should. An out of bounds index is an error, by any measure you'd care to use. Rather than going out of your way to cater to idiots, you should be forcing them to write good code to begin with.
    My best code is written with the delete key.

  7. #7
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Quote Originally Posted by Prelude
    >The reason for the capacity being a multiple of 2 is to prevent memory
    >fragmentation that occurs if odd-sized blocks of memory are allocated many times over.
    Okay, but that still doesn't answer why you allow any index by resizing the array. What happens if I accidentally say:
    Code:
    ArrayADT_setElement ( array, -1, my_val )
    This is a legitimate error, but your code will attempt to satisfy the request (with disatrous results) instead of going ballistic as it should. An out of bounds index is an error, by any measure you'd care to use. Rather than going out of your way to cater to idiots, you should be forcing them to write good code to begin with.
    Hehe.. Yeah I know it takes negative arguments but the program simply crashes perhaps even memory leaks I'm not too sure. I suppose I could add a few lines of code to fix this; I'll have to remmeber to ask my prof. what to do about negative indexes.

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I'll have to remmeber to ask my prof. what to do about negative indexes.
    Oh, is this a requirement for a class? In that case, please smack your instructor for me. The thing is that you don't handle negative indices, you only appear to. Your index type is unsigned, so a negative value will wrap around to a huge positive value and your code will attempt to allocate a lot of memory just to keep from throwing an error, which is a serious design flaw in my opinion. Most likely the crash you're getting is that your system's memory manager can't handle a single request for that much.
    My best code is written with the delete key.

  9. #9
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    I am aware of those issues but as far as I know they weren't specified as part of the program requirements. Of course it makes sense to put in a lot of error checking in a real program but I think the purpose of this program is not about that. Anyways, thanx for pointing out the glaring bug in my program

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory Problem with _beginthread()
    By nord in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 11:44 AM
  2. Problem Reading Process Memory
    By carrotcake1029 in forum C Programming
    Replies: 12
    Last Post: 04-14-2008, 10:33 AM
  3. Mysterious memory allocation problem
    By TomServo1 in forum C Programming
    Replies: 7
    Last Post: 07-08-2007, 11:29 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM