I have created a multilevel cache simulator, and to find the best performance cache, I have made loops that loop for quite a while.
Since each loop is allocating memory, with malloc, I freed up whatever it malloced, but I get this error when I run:
"incorrect checksum for freed object - object was probably modified after being freed"
Here's part of the code
Here's where it allocates memory:
/* cache1 */
if (S1 == 0) {
L1 = 1;
d_Cache1.cache_Array = (aBlock *)malloc((int)pow(2, (C1-B1)) * sizeof(aBlock));
/* static int cache1[(int)pow(2,(C1 - B1))]; */
} else if (S1 == C1-B1) {
L1 = 2;
f_Cache1.cache_Array = (aBlock *)malloc((int)pow(2, (C1-B1)) * sizeof(aBlock));
} else {
L1 = 3;
s_Cache1.cache_Array = malloc((int)pow(2, (C1 - S1 - B1))*sizeof(aBlock *));
if(s_Cache1.cache_Array == NULL){
fprintf(stderr, "out of memory\n");
return;
}
for (i = 0; i < (int)pow(2, (C1 - S1 - B1)); i++) {
s_Cache1.cache_Array[i] = malloc((int)pow(2, S1) * sizeof(aBlock));
if (s_Cache1.cache_Array[i] == NULL) {
fprintf(stderr, "out of memory\n");
return;
}
}
sc_Count1 = malloc((int)pow(2,S1) * sizeof(aBlock));
for (i = 0; i < (int)pow(2, S1); i++) {
sc_Count1[i] = 0;
}
}
and after performing everything, it frees up:
//cache1
if (S1 == 0) {
free(d_Cache1.cache_Array);
} else if (S1 == C1-B1) {
free(f_Cache1.cache_Array);
} else {
for (i = 0; i < (int)pow(2, (C1 - S1 - B1)); i++) {
free(s_Cache1.cache_Array[i]);
}
free(s_Cache1.cache_Array);
free(sc_Count1);
}
What could be causing this memory issue?
I'm freeing up the exact memory that i allocate, and value of S1, C1, B1 never changes until next loop.
Quite possibly the problem is in the middle - at least, I don't see where you do anything with the memory you malloc. Are you just zeroing out the array, or do you do something else with it? incorrect checksum for freed object - object was probably modified after being freed often comes from smashing the memory contents around the memory you malloc'd (that is, index out of bounds) or doing exactly what it's telling you - modifying the memory contents after freeing them - and that's my best guess as to what's happening.
As a measure of protection, when in debug mode, some compilers will put in a checksum around the memory to see if it gets modified after being freed, and if you do modify it, it won't match the checksum. The compiler is telling you you're messing with the contents of a chunk of memory that you have freed. Often times, the extra cost of check only happens when mallocing or freeing, so that's why it seems to be associated with those calls.
You may be tracking your malloc and frees just fine, but the next thing I would look at is the state of the memory when you write into it.
first
s_Cache1.cache_Array=malloc(...
then
s_Cache1.cache_Array[i]=malloc(..
Looks a bit suspicious in my eyes. malloc something within something already malloced?
Related
I do not know why I get Memory fault (core dumped) when I run this code
if (flg == 4) // PIPE
{
char **cmds;
char ***cmdarg;
int j=0;
cmds = split_str(cmd, "|");
for (i = 0; args[i] != NULL; i++)
{
if (strcmp(args[i], "|") == 1)
{
cmdarg[j][i]=args[i];
}
else
{
cmdarg[j][i+1] = NULL;
j++;
}
printf("%s\n",cmdarg[j][i]);
}
}
I am not so expert with pointers and arrays
cmdarg is not initialized. And I'm sure that GCC, when invoked as gcc -Wall -g, would have warned you about that.
You could keep its length, e.g.
int cmdarglen = 0;
Then initialize it to some suitable default size:
#define INITIAL_CMDARG_SIZE 10
cmdarg = calloc(INITIAL_CMDARG_SIZE, sizeof(*cmdarg));
if (!cmdarg) { perror("calloc cmdarg initial"); exit (EXIT_FAILURE); );
cmdarglen = INITIAL_CMDARG_SIZE;
then grow it when needed, e.g.
if (j >= cmdarglen) {
int newcmdarglen = 5*j/4+10;
char***newcmdarg = calloc(newcmdarglen, sizeof(*cmdarg));
if (!newcmdarg)
{ perror("calloc growing cmdarg"); exit(EXIT_FAILURE); };
memcpy (newcmdarg, cmdarg, sizeof(*cmdarg)*j);
free (cmdarg);
cmdarg = newcmdarg;
}
to be inserted appropriately inside your for loop. Of course, you probably need to initialize each element of cmdarg (by allocating them individually).
Don't forget to free(cmdarg) later.
At last, learn how to use the gdb debugger and valgrind memory leak detector.
You never initialize the cmdarg variable in you code. It will have an unspecified value, so when you dereference it, there is undefined behavior. In your case, this manifest by a segmentation fault.
I don't know what your code is trying to do, but what I can see is that you are reffering to an uninitialized variable 'cmdarg'.Another adivce: when possible (and I think that nearly always it is possible) try to avoid three levels of indirections (***).
My program crashes on this function on the 7th line, when I call malloc() when I run in release mode I get the `Program.exe has stopped working message, and when I run in debugger, most of the time it succeeds but sometimes I get this message (especially on larger input):
MONOM* polynomialsProduct(MONOM* poly1, int size1, MONOM* poly2, int size2, int* productSize)
{
int i1, i2;
int phSize = 1, logSize = 0;
MONOM* product;
product = (MONOM*)malloc(phSize*sizeof(MONOM));
monomAllocationVerification(product);
for (i1 = 0; i1 < size1; i1++)
{
for (i2 = 0; i2 < size2; i2++)
{
if (logSize == phSize)
{
phSize *= 2;
product = (MONOM*)realloc(product,phSize*sizeof(MONOM));
monomAllocationVerification(product);
}
product[logSize].coefficient = poly1[i1].coefficient * poly2[i2].coefficient;
product[logSize].power = poly1[i1].power + poly2[i2].power;
logSize++;
}
}
mergeSort(product,logSize);
*productSize = sumMonomsWithSamePower(product, logSize);
return product;
}
I understand that I'm dealing with memory errors and problems, but is there any quick way to analyze my code and look for memory errors? I look at my code a dozen of times looking for this kind of errors and found nothing. (I didn't want to post the code here since its 420 lines long).
First of all, if heap corruption is detected on the first malloc, that means it happened earlier (not in this function or on previous pass). So the problem may lie outside this code.
However, the code also looks suspicious to me.
monomAllocationVerification has no size parameter, so it should work on one monom only, yet you call it only once after realloc on pointer to first element, despite having allocated space for quite a few monoms. Please clarify your decision.
It is a bit unclear why sumMonomsWithSamePower should return a size, and thus modify an array to store a value. May be a quirk, but still suspicious.
UPDATE
The problem was in other functions; a few reallocs with wrong size.
I would check the return value of malloc() and use perror() to describe what error has occured. Also here is the documentation for malloc() and perror().
if((product = (MONOM*)malloc(phSize*sizeof(MONOM))) == NULL)
{
perror("ERROR: Failed to malloc ");
return 1;
//perror() will display a system specified string to describe the error it may tell you the error
}
Also do you know the size of MONOM? If not add the following line to your code.
printf("MONOM SIZE = %i\n", sizeof(MONOM));
I am student and I am writing HTTP proxy application in C. I have trouble with memory management. In all my previous applications I simply wrote a wrapper around malloc which aborted when malloc failed.
void *xmalloc(size_t size)
{
void *ptr;
assert(size);
ptr = malloc(size);
if (!ptr)
abort();
return ptr;
}
This I now find insufficient as I just want to refuse client and continue serving other clients when memory allocation fails due to temporary shortage of memory. If I don't want to clutter my code with checks after each malloc call (I have quite lot of them per function in parsing code), what are other options to handle memory management and which one is the best for my purposes and how what is a common way for server applications to handle memory management and shortage of memory?
Consider this function from my current code which parses one line from header portion of HTTP message (xstrndup calls xmalloc):
int http_header_parse(http_hdr_table *t, const char *s)
{
const char *p;
const char *b;
char *tmp_name;
char *tmp_value;
int ret = -1;
assert(t);
assert(s);
p = b = s;
/* field name */
for (; ; p++) {
if (*p == ':') {
if (p-b <= 0) goto out;
tmp_name = xstrndup(b, p-b);
b = ++p;
break;
}
if (is_ctl_char(*p) || is_sep_char(*p)) goto out;
}
while (*p == ' ' || *p == '\t') {
p++; b++;
}
/* field value */
for (; ; p++) {
if (is_crlf(p)) {
if (p-b <= 0) goto err_value;
tmp_value = xstrndup(b, p-b);
p += 2;
break;
}
if (!*p) goto err_value;
}
http_hdr_table_set(t, tmp_name, tmp_value);
ret = 0;
xfree(tmp_value);
err_value:
xfree(tmp_name);
out:
return ret;
}
I would like to keep things simple and handle memory allocation errors at one place and to not clutter code with malloc error handling code. What should I do? Thank you.
P.S: I am writing the application to run on POSIX/Unix-like systems. Also feel free to criticize my current coding style and practices.
If you want to use a relatively low level language like C, then you shouldn't be too worried about adding something like if(tmp_value == NULL) goto out; in 2 places.
If you can't stand the idea of 2 trivial lines of extra code, then maybe try a language that supports exceptions properly (e.g. C++) and add throw/try/catch instead. Note: I really don't like C++, but using C++ would have to make more sense than implementing your own "exception like" features and an entire layer of automated resource de-allocation in C.
Modern languages give you garbage collection and exceptions. C doesn't, so you have to work hard. There's no magical solution here.
Some tips:
Create a session structure, and keep all your allocated memory pointed from it. When the session is aborted, always call a cleanup function. This way, even if you have to check for failures in many places, at least all failures are handled the same way.
You can even create a session_allocate() function, which allocates memory and keeps it on a linked list pointed from the session structure. Everything you allocate using this function would be freed when the session is destroy.
Try to concentrate all allocations in the beginning of the session. After you've allocated all you need, the rest of your code won't need to worry about failures.
If you're on a system that supports fork(), which linux does, you can run each client connection in it's own process. When a client connection is first established, you fork your main process into a child process to handle the rest of the request. Then you can abort() like you always have and only the specific client connection is affected. This is a classic unix server model.
If you don't want to or can't use fork(), you need to abort the request by throwing an exception. In C, that would be done by using setjump() when the connection is first established and then calling longjump() when out of memory is detected. This will reset execution and the stack back to where setjump() was called.
The problem is, this will leak all the resources allocated up to that point (for example, other memory allocations that had succeeded up to the point of getting out of memory). So additionally, your memory allocator will have to track all the memory allocations for each request. When longjump() is called, the setjump() return location will then have to free all the memory that was associated with the aborted request.
This is what apache does using pools. Apache uses pools to track resource allocations so it can auto free them in the case of an abort or because the code just didn't free it: http://www.apachetutor.org/dev/pools.
You should also consider the pool model and not just simply wrap malloc() so one client can't use up all the memory in the system.
Another possibility would be to use Boehm's GC by using its GC_malloc instead of malloc (you won't need to call free or GC_free); its
GC_oom_fn function pointer (called internally from GC_malloc when no memory is available any more) can be set to your particular out of memory handler (which would deny the incoming HTTP request, perhaps with a longjmp)
The major advantage of using Boehm GC is that you don't care any more about free-ing your dynamically allocated data (provided it was allocated using GC_malloc or friends, e.g. GC_malloc_atomic for data without any pointers inside).
Notice that memory management is not a modular property. The liveness of some given data is a whole program property, see garbage collection wikipage, and RAII programming idiom.
You could of course use alloca, but that has issues that mean it must be used with care. Alternatively, you can write your code so that you minimise and localise the use of malloc. For example your function above could be rewritten to localise the allocations:
static size_t field_name_length(const char *s)
{
const char *p = s;
for ( ; *p != ':'; ++p) {
if (is_ctl_char(*p) || is_sep_char(*p))
return 0;
}
return (size_t) (p - s);
}
static size_t value_length(const char *s)
{
const char *p = s;
for (; *p && !is_crlf(p); p+=2) {
/* nothing */
}
return *p ? (size_t) (p - s) : 0;
}
int http_header_parse(http_hdr_table *t, const char *s)
{
const char *v;
int ret = -1;
size_t v_len = 0;
size_t f_len = field_name_length(s);
if (f_len) {
v = s + f_len + 1;
v = s + strspn(s, " \t");
v_len = value_length(s);
}
if (v_len > 0 && f_len > 0) {
/* Allocation is localised to this block */
const char *name = xstrndup(s, f_len);
const char *value = xstrndup(v, v_len);
if (name && value) {
http_hdr_table_set(t, name, value);
ret = 0;
}
xfree(value);
xfree(name);
}
return ret;
}
Or, even better, you could modify http_hdr_table_set to accept the pointers and lengths and avoid allocation completely.
I'm getting an error in valgrind and don't know what is wrong.
The error is:
valgrind output:
==1112== Conditional jump or move depends on uninitialised value(s)
==1112== at 0x402BF0D: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
And it states the problem occurs on line 226:
if(reallocate ==TRUE)
{
char** temp_values = NULL;
temp_values = (char**) realloc(theBoard->_values, theBoard->_size_r*sizeof(char*) );
if(temp_values!=NULL)
{
theBoard->_values = temp_values;
} else
{
reportError(MEM_OUT);
return FALSE;
}
int i = 0;
for (i=0; i<theBoard->_size_r; i++)
{
char* temp_values_c = NULL;
HERE( line 226)-> temp_values_c = realloc(theBoard->_values[i], theBoard->_size_c*sizeof(char) );
if(temp_values_c != NULL)
{
theBoard->_values[i] = temp_values_c;
} else
{
reportError(MEM_OUT);
return FALSE;
}
}
// initialize extra memory
if(row_out_bound)
{
init(theBoard,prev_size_r,0);
}
if(col_out_bound)
{
init(theBoard,0, prev_size_c);
}
}
Why is this happening and how can i fix it?
The problem is theBoard->_values[i] is not initialized since it comes straight from realloc (temp_values = ...).
EDIT
Can you elaborate please?
I thought you'd never ask. The function realloc returns a chunk of memory of the specified size, with no guarantees regarding its contents. So for all practical purposes you should assume anything realloc returns contains garbage. In your code you take that (potential) garbage and on line 226 you tell realloc:
Here's this pointer that's like totally valid and all. It's NULL or I previously obtained it from malloc. Can you realloc it to this size? And that's not true! The actual value contained by theBoard->_values[i] could be anything.
What you want is a loop that does theBoard->_values[i] = NULL, or maybe use malloc instead of realloc on line 226.
I'm attempting to write a solver for a particular puzzle. It tries to find a solution by trying every possible move one at a time until it finds a solution. The first version tried to solve it depth-first by continually trying moves until it failed, then backtracking, but this turned out to be too slow. I have rewritten it to be breadth-first using a queue structure, but I'm having problems with memory management.
Here are the relevant parts:
int main(int argc, char *argv[])
{
...
int solved = 0;
do {
solved = solver(queue);
} while (!solved && !pblListIsEmpty(queue));
...
}
int solver(PblList *queue) {
state_t *state = (state_t *) pblListPoll(queue);
if (is_solution(state->pucks)) {
print_solution(state);
return 1;
}
state_t *state_cp;
puck new_location;
for (int p = 0; p < puck_count; p++) {
for (dir i = NORTH; i <= WEST; i++) {
if (!rules(state->pucks, p, i)) continue;
new_location = in_dir(state->pucks, p, i);
if (new_location.x != -1) {
state_cp = (state_t *) malloc(sizeof(state_t));
state_cp->move.from = state->pucks[p];
state_cp->move.direction = i;
state_cp->prev = state;
state_cp->pucks = (puck *) malloc (puck_count * sizeof(puck));
memcpy(state_cp->pucks, state->pucks, puck_count * sizeof(puck)); /*CRASH*/
state_cp->pucks[p] = new_location;
pblListPush(queue, state_cp);
}
}
}
free(state->pucks);
return 0;
}
When I run it I get the error:
ice(90175) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Bus error
The error happens around iteration 93,000.
From what I can tell, the error message is from malloc failing, and the bus error is from the memcpy after it.
I have a hard time believing that I'm running out of memory, since each game state is only ~400 bytes. Yet that does seem to be what's happening, seeing as the activity monitor reports that it is using 3.99GB before it crashes. I'm using http://www.mission-base.com/peter/source/ for the queue structure (it's a linked list).
Clearly I'm doing something dumb. Any suggestions?
Check the result of malloc. If it's NULL, you might want to print out the length of that queue.
Also, the code snippet you posted didn't include any frees...
You need to free() the memory you've allocated manually after you're done with it; dynamic memory doesn't just "free itself"