Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Strange error when reallocating memory

Reply
Thread Tools

Strange error when reallocating memory

 
 
francesco
Guest
Posts: n/a
 
      12-23-2012

>
> per il resto, quando ho visto m=2^n e m usato come parametro per malloc
> ed come parametro per il ciclo for: ho abbandonato...


Devo allocare un blocco di m strutture,e poi riempirle. Quindi mi serve
sia malloc con m come parametro sia ripetere il ciclo di for m volte

Francesco
 
Reply With Quote
 
 
 
 
Ike Naar
Guest
Posts: n/a
 
      12-23-2012
On 2012-12-22, francesco <(E-Mail Removed)> wrote:
>>
>> You have an error at line 42.

>
> Sorry, this is he code
>
> #include<stdlib.h>
> #include<stdio.h>
> typedef struct {
> int *ptrSet;
> int elementi;
> }Set;
> int pot(int base,int esponente);
> void stamparesti( int *resti, int n);
> int main()
> {
> Set *ptrPDS=NULL;
> int *ptr2Set=NULL;
> int *resti=NULL;
> int *set=NULL;
> int n,m;
> int i=0,j=0;
> int N,Q=0;
> int card=0;
> printf("Inserisci il numero di elementi di S\n");
> scanf("%d",&n);
> m=pot(2,n);
> printf("L'insieme dei sottoinsiemi di un insieme S ha %d sottoinsiemi
> \n",m);
> ptrPDS=(Set *)malloc(sizeof(Set)*m);
> if(ptrPDS==NULL)
> {
> printf("Impossibile allocare spazio per l'insieme PDS: memoria
> insufficiente\n");
> free(ptrPDS);
> exit(1);
> }
> set=malloc(sizeof(int)*n);
> // Verifica se esiste abbastanza memoria per l'allocazione dell'insieme
> if(set==NULL)
> {
> printf("Impossibile allocare spazio per l'insieme S: memoria
> insufficiente\n");
> free(set);
> exit(1);
> }
>
> printf("Iserire gli elementi di S\n");
> for(i=0;i<n;i++)
> {
> printf("\nInserire elemento %d",i);scanf("%d",set+i);
> }
> for(i=0;i<m;i++)
> {
> printf("i=%d\n",i);
> resti=malloc(sizeof(int)*n);
> if(resti==NULL)
> {
> printf("Impossibile allocare spazio per l'insieme S:
> memoria insufficiente\n");
> free(resti);
> exit(1);
> }
> N=i;
> //Conversione in binario del numero i
> for(j=0;j<n;j++)
> {
> Q=N/2;
> *(resti+j)=N%2;
> N=Q;
> }
> stamparesti(resti,n);
> ptr2Set=malloc(sizeof(int));
> if(ptr2Set==NULL)
> {
> printf("Allocazione di memoria non riuscita\n");
> free(ptr2Set);
> exit(1);
> }
> card=0;
> for(j=0;j<n;j++)
> {
> printf("j=%d card=%d\t",j,card);
> if(*(resti+j)==1)
> {
> ptr2Set=realloc(ptr2Set,++card);
> if(ptr2Set==NULL)
> {
> printf("Allocazione di memoria non riuscita\n");
> free(ptr2Set);
> exit(1);
> }
> *(ptr2Set+card-1)=*(set+j);
> }
> }
> free(resti);
> (ptrPDS+i)->elementi=card;
> (ptrPDS+i)->ptrSet=ptr2Set;
> printf("i=%d\telementi=%d\tptrSet=%p\n",i,card,ptr 2Set);
> }
> // Stampa elementi sottoinsieme.
> for(i=0;i<m;i++)
> {
> ptr2Set=(ptrPDS+i)->ptrSet;
> printf("S%d={",i);
> card=(ptrPDS+i)->elementi;
> if (card==0) printf("}\n");
> else
> {
> for(j=0;j<card-1;j++) printf("%d,",*(ptr2Set+j));
> printf("%d}\n",*(ptr2Set+j));
> }
> printf("\n");
>
> }
> free(ptrPDS);
> free(ptr2Set);


There is a malloc/free mismatch here.
You allocate n regions of memory, using ptr2Set=malloc(/*...*/) in a loop,
but only one of them is freed at the end of the program.

> free(set);
> return 0;
> }

 
Reply With Quote
 
 
 
 
francesco
Guest
Posts: n/a
 
      12-24-2012
Il Sun, 23 Dec 2012 17:12:01 -0500, pete ha scritto:

> pete wrote:
>>
>> Ike Naar wrote:
>> >
>> > On 2012-12-22, francesco <(E-Mail Removed)> wrote:

>>
>> > > for(i=0;i<m;i++)
>> > > {

>>
>> > > (ptrPDS+i)->elementi=card;
>> > > (ptrPDS+i)->ptrSet=ptr2Set;
>> > > printf("i=%d\telementi=%d\tptrSet=%p\n",i,card,ptr 2Set);

>> /*
>> ** I think that the free(ptr2Set); statement ** should be relocated to
>> right here,
>> ** to avoid the {allocation / free} mismatch,
>> ** which was mentioned by Ike Naar.
>> */
>> > > }
>> > > // Stampa elementi sottoinsieme.
>> > > for(i=0;i<m;i++)
>> > > {
>> > > ptr2Set=(ptrPDS+i)->ptrSet;
>> > > printf("S%d={",i);
>> > > card=(ptrPDS+i)->elementi;
>> > > if (card==0) printf("}\n");
>> > > else {
>> > > for(j=0;j<card-1;j++) printf("%d,",*(ptr2Set+j));
>> > > printf("%d}\n",*(ptr2Set+j));
>> > > }
>> > > printf("\n");
>> > >
>> > > }
>> > > free(ptrPDS);
>> > > free(ptr2Set);

>>
>> > There is a malloc/free mismatch here.
>> > You allocate n regions of memory, using ptr2Set=malloc(/*...*/)
>> > in a loop,
>> > but only one of them is freed at the end of the program.
>> >
>> > > free(set);
>> > > return 0;
>> > > }

>
> After thinking more,
> I think that it makes more sense to allocate (ptr2Set) prior to the
> loop,
> and to then free it after the loop.


As I did it

>
> And it also makes more sense to allocate (resti) prior to the loop, and
> to then free it after the loop.


>
> puts("Inserisci il numero di elementi di S"); scanf("%d", &n);
> m = pot(2, n);
> printf("L'insieme dei sottoinsiemi di un insieme S ha %d"
> " sottoinsiemi\n", m);
> ptrPDS = malloc(m * sizeof *ptrPDS);
> set = malloc(n * sizeof *set);
> resti = malloc(n * sizeof *resti);

resti is an array of int values, dinamically created
> ptr2Set = malloc(sizeof *ptr2Set);

ptr2Set is an array of int values, dinamically created
> /*
> ** Verifica se esiste abbastanza ** memoria per l'allocazione
> dell'insieme */
> if (ptrPDS == NULL || set == NULL
> || resti == NULL || ptr2Set == NULL)
> {
> free(resti);
> free(set);
> free(ptrPDS);
> free(ptr2Set);
> puts("Allocazione di memoria non riuscita"); exit(EXIT_FAILURE);
> }
> puts("Iserire gli elementi di S");
> for (i = 0; n > i; ++i) {
> printf("\nInserire elemento %d ", i);
> fflush(stdout);
> scanf("%d", set + i);
> }
> for (i = 0; m > i; ++i) {
> printf("i=%d ", i);
> N = i;
> /*
> ** Conversione in binario del numero i */
> for (j = 0; n > j; ++j) {
> Q = N / 2;
> resti[j] = N % 2;
> N = Q;
> }
> stamparesti(resti, n);
> card = 0;
> for (j = 0; n > j; ++j) {
> printf("j=%d card=%d\n", j, card);
> if (resti[j] == 1) {
> void *temp;
>
> temp = realloc(ptr2Set, (card + 1) * sizeof *ptr2Set);
> if (temp == NULL) {
> free(ptr2Set);
> free(resti);
> free(set);
> free(ptrPDS);
> puts("Allocazione di memoria non riuscita");
> exit(EXIT_FAILURE);
> }
> ptr2Set = temp;
> ptr2Set[card++] = set[j];
> }
> }
> ptrPDS[i].elementi = card;
> ptrPDS[i].ptrSet = ptr2Set;
> printf("elementi=%d ptrSet=%p\n\n\n\n", card, ptr2Set);
> }
> free(ptr2Set);
> free(resti);
> free(set);


Thak you for your advices.

Francesco
 
Reply With Quote
 
Ralph Spitzner
Guest
Posts: n/a
 
      12-24-2012
Phil Carmody wrote:
[...]
>> if(set==NULL)
>> {
>> printf("Impossibile allocare spazio per l'insieme S: memoria
>> insufficiente\n");
>> free(set);

>
> pointless
>


Apart from it being pointless he's actually trying to free a
NULL pointer

-rasp



--
Where's that ****ing 'any' key ?
 
Reply With Quote
 
Richard Damon
Guest
Posts: n/a
 
      12-24-2012
On 12/24/12 9:51 AM, Ralph Spitzner wrote:
> Phil Carmody wrote:
> [...]
>>> if(set==NULL)
>>> {
>>> printf("Impossibile allocare spazio per l'insieme S: memoria
>>> insufficiente\n");
>>> free(set);

>>
>> pointless
>>

>
> Apart from it being pointless he's actually trying to free a
> NULL pointer
>
> -rasp


It is perfectly legal to free a null pointer. The free() function has
defined behavior in this case, it does nothing.

The fact that he KNOWS it is a null pointer, is what makes the call
pointless, it just becomes a waste of a few CPU cycles.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      12-24-2012
On 12/24/2012 09:51 AM, Ralph Spitzner wrote:
> Phil Carmody wrote:
> [...]
>>> if(set==NULL)
>>> {
>>> printf("Impossibile allocare spazio per l'insieme S: memoria
>>> insufficiente\n");
>>> free(set);

>>
>> pointless
>>

>
> Apart from it being pointless he's actually trying to free a
> NULL pointer


"NULL" is the name of a standard macro that's required to expand into a
null pointer constant - due to one of the quirks of C jargon, a null
pointer constant is not necessarily a pointer, null or otherwise; it can
be an integer. He's calling free(set), not free(NULL). In the comparison
between set and NULL, NULL gets converted to a null pointer of the same
type as "set"; if that branch has been entered, they compared equal,
which means that "set" is also a null pointer. The word you should have
used was "null", not "NULL".
--
James Kuyper
 
Reply With Quote
 
James Harris
Guest
Posts: n/a
 
      12-24-2012
On Dec 23, 9:22*pm, pete <(E-Mail Removed)> wrote:
> James Harris wrote:
>
> > On Dec 22, 6:09 pm, francesco <(E-Mail Removed)> wrote:
> > > I get this strange error message

>
> > > subsets.exe: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr)

>
> > An assertion failure in malloc suggests you have previously
> > overwritten one or more of its internal data structures. They are
> > often placed between the spaces malloc/realloc gives to you and should
> > not be touched.

>
> > In your code I see

>
> > * *(ptr2Set+card-1)=*(set+j);

>
> > Is this right? It looks like card starts out as zero so this could
> > refer to the memory before your allocated area that you should not
> > touch. This may be it - or there may be others.

>
> card is incremented as a function call argument
> prior to that line.


Sure, you're right. I didn't want to spend the time to understand the
OP's specific code so I made that part of my post a question rather
than a statement. It was meant to illustrate the potential issue
rather than be the specific cause. The main point of the post was the
part about corrupting malloc/realloc data structures.

> I don't increment arguments in function calls,
> because I've been advised against it
> as a matter of style.


Interesting. I can't see a problem with it.

James
 
Reply With Quote
 
Phil Carmody
Guest
Posts: n/a
 
      12-25-2012
Ralph Spitzner <(E-Mail Removed)> writes:
> Phil Carmody wrote:
> [...]
> >> if(set==NULL)
> >> {
> >> printf("Impossibile allocare spazio per l'insieme S: memoria
> >> insufficiente\n");
> >> free(set);

> >
> > pointless
> >

>
> Apart from it being pointless he's actually trying to free a
> NULL pointer


No, that *is* the pointless bit. It's nothing more than pointless though.
(Apart from it also being a warning sign about what to expect elsewhere
in the code.)

Phil
--
I'm not saying that google groups censors my posts, but there's a strong link
between me saying "google groups sucks" in articles, and them disappearing.

Oh - I guess I might be saying that google groups censors my posts.
 
Reply With Quote
 
army1987
Guest
Posts: n/a
 
      12-27-2012
On Sat, 22 Dec 2012 20:32:37 +0000, BartC wrote:

> (BTW the layout of your code could be improved!)


I suspect he's using tab characters to indent, but something along the
line (his newsreader, his news server, your news server, your newsreader)
strips them away.



--
[ T H I S S P A C E I S F O R R E N T ]
Troppo poca cultura ci rende ignoranti, troppa ci rende folli.
-- fathermckenzie di it.cultura.linguistica.italiano
<http://xkcd.com/397/>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
AVG Email Scanner activating at strange times with strange IP addresses dennispublic@hotmail.com Computer Support 1 08-26-2006 04:27 AM
Strange memory access error after calling dll Mongoose7 C++ 2 03-08-2006 05:31 PM
Strange error of memory sylsau C Programming 9 11-22-2005 05:17 PM
Differences between Sony Memory Stick & memory Stick Pro vs Memory Stick Duo? zxcvar Digital Photography 3 11-28-2004 10:48 PM
Question About Strange 'C' Code Syntax ( Well strange to me anyway ) Harvey Twyman C Programming 8 10-25-2003 05:54 AM



Advertisments