Hey,
My programs crashes after the 27th time i call realloc. Is there a limit in realloc or what else could it be?
Hey,
My programs crashes after the 27th time i call realloc. Is there a limit in realloc or what else could it be?
You need to show some code.
One common mistake is ignoring the return result of realloc.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
There is no pre-determined limit as to the number of times you can call realloc, but there is a limit as to the amount of contiguous memory available, so you could be running out of that, upon which realloc should return a null pointer. If you don't check for that null pointer, you would then end up dereferencing a null pointer, for which a crash is one possible symptom.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
After realloc i am checking if the pointer if null, if it is it returns. Thats why i am kinda confused, my program crashes instead of returning.
Well like I said, post your code or deal with wild guesses.
You're trashing memory somewhere else in your code, and this just happens to be where it finally fails.
It's nothing to do with realloc, or the number of times you call it.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Code:typedef struct { long unsigned int code; fullName name; short unsigned int matches; } registers; typedef struct{ registers **rgs; int size; int empty; } tableOfRegisters; int init(tableOfRegisters *tableRgs, int size){ registers *tmp; tableOfRegisters *table; tmp = (registers *) malloc(size * sizeof(registers)); table = (tableOfRegisters *) malloc(sizeof(tableOfRegisters)); if(tmp == NULL || table == NULL){ free(tmp); free(table); return 0; } *tableRgs = *table; tableRgs->rgs = tmp; tableRgs->size = size; tableRgs->empty = size; return 1; } int add(tableOfRegisters *tableRgs, long unsigned int code, char *firstName, char *lastName, short unsigned int matches, int k){ registers *tablerg, *rg; int pos,temp; if(tableRgs->size == 0){ temp = init(tableRgs, k); if(temp == 0){ return 0; } } pos = find0(tableRgs,code); if (pos != -1) { return 0; } if (tableRgs->empty == 0) { tablerg = (registers *) realloc(*tableRgs->rgs, (tableRgs->size + k) * sizeof(registers)); if (tablerg == NULL) { free(tablerg); return 0; } *tableRgs->rgs = tablerg; tableRgs->size += k; tableRgs->empty += k; } rg = (registers *) malloc(sizeof(registers)); if(rg == NULL){ free(rg); return 0; } rg->code = code; rg->matches = macthes; strcpy(rg->name.lastName, lastName); strcpy(rg->name.firstName, firstName); tableRgs->rgs[tableRgs->size - tableRgs->empty] = rg; tableRgs->empty--; return 1; }
Where is your main() ?
> tmp = (registers *) malloc(size * sizeof(registers));
There's no need to cast malloc in a C program.
In fact, it can be used to hide bugs.
See the FAQ
> *tableRgs = *table;
This is NOT saving your pointer.
> tableRgs->rgs = tmp;
But rgs is a 'registers**' but tmp is only a 'registers*'
If you have warnings like this, you're wasting your time trying to debug it, because it's already broken.Code:bar.c: In function ‘init’: bar.c:34:19: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types] tableRgs->rgs = tmp;
Please tell me that you did actually copy/paste this from your compiled source code, and not as it seems like something you typed from memory on your phone.Code:bar.c:80:19: error: ‘macthes’ undeclared (first use in this function) rg->matches = macthes;
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
>There is a need to cast malloc in C since the exercise says so.
>How should i make tableRgs be the pointer I get from malloc.
> There is a need to cast malloc in C since the exercise says so.
Your tutor / book / website is sadly mis-informed.
In case you didn't bother to read the FAQ, let me summarise.
If you don't include stdlib.h, and you cast malloc, then your code is BROKEN!.
You just gagged the compiler from telling you about a mistake.
Your 'need' is perhaps someone is using a C++ compiler to compile C code.
You can find out easily by giving them this program.
Anyway, rant over.Code:#include<stdio.h> int main(void) { printf("%d\n",(int)sizeof('a')); return 0; } # compiled as C, this will print 4 on most machines you're likely to be using # Possibly 2 if you're a DOS throwback, possibly 8 if you're super into 64-bit computing # Very outside chance of being 1 on some exotic DSP chips $ gcc foo.c $ ./a.out 4 # C++ guarantees the answer will be 1 $ gcc -x c++ foo.c $ ./a.out 1
This is how you use realloc to create an expanding container.
It looks like this.Code:#include <stdlib.h> #include <stdio.h> typedef struct { char firstName[30]; char lastName[30]; } fullName; typedef struct { long unsigned int code; fullName name; short unsigned int matches; } registers; typedef struct { registers *rgs; int size; // The allocated space int len; // The number presently used } tableOfRegisters; int add(tableOfRegisters *table, long unsigned int code, char *firstName, char *lastName, short unsigned int matches) { if ( table->size == table->len ) { // if the size is 0, start with 10, otherwise just double the size each time int newsize = table->size == 0 ? 10 : table->size * 2; printf("DEBUG: extending table from %d to %d\n", table->size, newsize); void *temp = realloc(table->rgs, newsize * sizeof(*table->rgs) ); if ( temp ) { table->rgs = temp; table->size = newsize; } else { return -1; // error, could not extend } } table->rgs[table->len].code = code; // ditto other fields table->len++; return 0; // OK } int main ( ) { // there is no need to call malloc initially, realloc(NULL,size) == malloc(size) tableOfRegisters table = { 0 }; for ( long unsigned int code = 0 ; code < 100 ; code++ ) { add(&table, code, "", "", 0); } for ( int i = 0 ; i < table.len ; i++ ) { printf("%d: code=%lu\n", i, table.rgs[i].code); } free(table.rgs); }
Code:$ gcc bar.c $ ./a.out DEBUG: extending table from 0 to 10 DEBUG: extending table from 10 to 20 DEBUG: extending table from 20 to 40 DEBUG: extending table from 40 to 80 DEBUG: extending table from 80 to 160 0: code=0 1: code=1 2: code=2 3: code=3 <<snipped>> 96: code=96 97: code=97 98: code=98 99: code=99
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Computers can run out of memory. But if you are making valid allocations in a small beginner's program on a desktop machine, this is very unlikely.
You need to test the return from realloc() for null to rule this out.
Another way it can crash is if you pass a pointer not allocated with malloc / realloc. That's a fault in your logic somewhere. It's quite hard to find without a memory checking tool, since valid pointers not returned form malloc() don't look very different to valid pointers returned from malloc(), but only the second sort can be passed to realloc().
I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
Visit my website for lots of associated C programming resources.
https://github.com/MalcolmMcLean
Freeing a NULL pointer can cause a crash with some C Compilers.Code:if(rg == NULL){ free(rg); return 0; }
No idea if that is true with yours!
I think the C++ Compilers are supposed to not error out when freeing a NULL pointer; but, I am not sure whether that is only true for deleting a NULL pointer.
Tim S.
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
The only systems I'm aware of are 3BSD, PalmOS, and Novell NetWare. Considering how old and/or esoteric these systems are (3BSD was released in 1980 (10 years before C was standardized), PalmOS was discontinued in 2009, and NetWare was last released in 2009), I would consider these to be very niche systems at this point.
If you're still working on any of those systems, you have to check for a null pointer before freeing it, otherwise it should be fairly safe to assume that you don't have to.
ISO/IEC 9899:TC3
7.20.3.2:
"The free function causes the space pointed to by ptr to be deallocated, that is, made
available for further allocation. If ptr is a null pointer, no action occurs..."