• Advertisement
Sign in to follow this  

new operator allocates too little memory

This topic is 4041 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using gcc 3.3.1 (mingw special 20030804-1) and got a weird problem creating structures:
struct Entry
 {
 void                                  *ptr;
 struct Entry                          *prev, *next;
 };

void somefunction()
{
    // This code allocates less memory than needed - not always but only in some cases (resulting in a read access exception)
    Entry *e = new Entry;

    // However, the same happens here:
    Entry *e = (Entry*)malloc(sizeof(Entry));

    // So I thought it must be an alignment problem because the following code works:
    Entry *e = (Entry*)malloc(sizeof(Entry)+32);
}

Now what am I doing wrong?

Share this post


Link to post
Share on other sites
Advertisement
try in main:

int s = sizeof(Entry);

on 32 bit platform it should give 12 bytes and it already aligned. access exception is probably there becuse you forgot to do:

e->next = new Entry;

Share this post


Link to post
Share on other sites
Yes it's actually 12 bytes. And I do not have any mistakes in the code as you suggested... It's some kinde of alignment problem.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by AndiDog
And I do not have any mistakes in the code as you suggested...


Famous last words...

How about posting the actual code instead of just a few lines from here and there?

Share this post


Link to post
Share on other sites
I assure you new works correctly.
The problem lies elsewhere in your code, likely you are trying to use the pointers in Entry without properly initializing them or you're doing something nasty and illegal with that void pointer.

This is C++, so why not use templates instead of void*?

Share this post


Link to post
Share on other sites
In addition your first mistake is not to add a constructor to your "Entry" structure. Many problems arise from unitialised variables, so you'd best introduce a few ctors:

template<class Payload>
struct Entry
{
typedef Payload value_type;
typedef Payload* value_pointer;

Entry() : prev(0), next(0), ptr(0) {
}
Entry(Payload * ptr, Entry * prev = 0, Entry * next = 0) :
ptr(ptr), prev(prev), next(next) {
}
Payload *ptr;
Entry *prev;
Entry *next;
};




Cheers,
Pat

Share this post


Link to post
Share on other sites
I don't use a constructor because I zero the struct before usage.

My code is far too complex to post it here.

The program does not crash if I allocate more memory than "needed" - and that's what I don't understand. Anyway I'm sure it's my fault (as always).

Share this post


Link to post
Share on other sites
1) If you can use 'new', you are in C++. Use std::list. Better yet, choose appropriately from std::list, std::vector, and std::deque.

2) What's your evidence for "less memory than needed" being allocated? How are you measuring the allocation? Or does it just crash?

3) If you can use 'new', you are in C++. Don't use void*'s; template stuff.

4) You are aware, of course, that a void* is still a pointer? I.e. it's not a magical provider-of-storage-for-things-unknown; it still has to be pointed at something. What are you pointing it at? Did you make an allocation for the pointed-at thing as well? Do you need to?

5) You aren't, by any chance, (at least temporarily) ignorant of all of the above, and writing to the .ptr member as if it were a value rather than a pointer? (Don't laugh; I've seen it happen.) Is it possible the sizeof() the type you're using is something greater than sizeof(void*) but less than or equal to sizeof(void*) + 32? :/

6) Even if you know what you're doing, I can still assure you with great confidence that 'new' works properly. But anyway, those of us who could create and use this 'Entry' properly the first time, and have everything just work, still use std::list. You should too.

Share this post


Link to post
Share on other sites
Sounds quite logical :) but why should I use C++ std::list if I am too stupid to code my own *simple* list template class?

I just got another idea: If there's a problem with a read access exception, why don't I look for the code accessing the memory??? Gonna do that right now...

Thanks

Share this post


Link to post
Share on other sites
Quote:
Original post by AndiDog
Sounds quite logical :) but why should I use C++ std::list if I am too stupid to code my own *simple* list template class?

Because coding your own list is not simple. [wink]

Share this post


Link to post
Share on other sites
Quote:
Original post by AndiDog
Sounds quite logical :) but why should I use C++ std::list if I am too stupid to code my own *simple* list template class?

Why should you use new or malloc if you are too stupid to implement your own memory manager?

BTW, I firmly feel that all programmers should be able to implement data structures. I just don't know whether that's what you want to learn now. Just keep in mind that it's not a prerequisite to using the standard library.

Share this post


Link to post
Share on other sites
Quote:
Original post by AndiDog
Sounds quite logical :) but why should I use C++ std::list if I am too stupid to code my own *simple* list template class?


Well, if you can't get it right yourself, and you don't use the standard version, what are you going to use instead? You need *something*... :)

And if you *can* get it right yourself... why spend the time on it when there's something provided for you that (a) is as efficient as it realistically can be for what it does and (b) is - well - *provided for you*? :) (Obviously, the standards committee can't write your program for you; but certain concepts - like storing a sequence of objects of the same type in a "container" - are so common that they put together robust yet low-overhead solutions for those problems.)

Of course, you do still get to use your brain here - to choose between std::list, std::vector and std::deque. They implement different strategies for holding a sequence of items, because none is best for all situations (and there isn't really a good way to take the best of each, either - you pretty much have to choose each time).

Note that if you got the idea to make your own list on account of some formal CS education, that - well, CS education generally sucks in that regard :) Profs love to teach linked lists, but people could graduate from these programs not even knowing there are other ways (i.e. the strategies implemented by std::vector and std::deque), because they aren't encouraged to *think* about such things. Certainly they don't teach them directly - no, lists are just too "elegant" to bother with anything else :S

Share this post


Link to post
Share on other sites
Checking that using the structure properly isn't causing the read access violation is easy.

Entry *e = new Entry;
e->ptr = 0;
e->prev = 0;
e->next = 0;

If that doesn't cause an access violation then why would writing to it somewhere else cause one?

And like everyone's been saying, since this is C++ why are you using void*?

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Note that if you got the idea to make your own list on account of some formal CS education, that - well, CS education generally sucks in that regard :) Profs love to teach linked lists, but people could graduate from these programs not even knowing there are other ways

Yikes, really?
I obviously only have experience with CS where I'm studying, but that's not the case here, at least. Sounds.... scary [grin]

Share this post


Link to post
Share on other sites
Quote:
Original post by Spoonbender
Quote:
Original post by Zahlman
Note that if you got the idea to make your own list on account of some formal CS education, that - well, CS education generally sucks in that regard :) Profs love to teach linked lists, but people could graduate from these programs not even knowing there are other ways

Yikes, really?
I obviously only have experience with CS where I'm studying, but that's not the case here, at least. Sounds.... scary [grin]


I've begun to think that American CS courses must be bad, because they keep bagging them. Ours aren't like that.

Anyway, AndiDog seems to be a C programmer who refuses to let the features of C++ take over the tedious parts of programming for him. Misconceptions about control and speed, probably. If he was using C, that'd be no problem, but he's using C++, and his huge project would be a million times more manageable. Eh.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
It's ok. It's likely the OS, language or environment he's using causing the problems. He's the best programmer EVER to live. It will be decades before anyone like him comes along again. Embrace his flawless C/C++ but ignore the useful parts of C++ skills!

Remember void * is your bestest friend and VERY safe. Template are evil and the spawn of Satan. All hail Satan.

Share this post


Link to post
Share on other sites
Quote:
Original post by AndiDog
I don't use a constructor because I zero the struct before usage.

My code is far too complex to post it here.

The program does not crash if I allocate more memory than "needed" - and that's what I don't understand. Anyway I'm sure it's my fault (as always).


You're almost certainly accidentally writing beyond the bounds of your struct at some point - so allocating an extra 32bits of storage stops your program crashing.

Share this post


Link to post
Share on other sites
@Anonymous Poster: Real funny... of course I ain't the one and only programmer (that's why I created this thread!) [wink]

Got my solution now: I removed the (prev) member in the struct because I don't use it in the code, and now it works...

O.K. I gotta admit there was a mistake in my code :)

Share this post


Link to post
Share on other sites
you should either program in c++ or c pick one or the other or at least keep one separate from the other.

When you are working with pointers error checking can save you tons of time. testing to see if your pointers are valid and reporting when they are not. always zero your pointers your self and before you use them test to make sure they are not zeroed. this has gone a long way in reducing my access violations with pointer

good luck

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement