c free() crashing: No source available for "ntdll!RtlpNtEnumerateSubKey() - c

My program crached on Eclipse when i try to free my object - PokemonTrainer.I have tried the solution in this article, but it didn't help.
PokemonTrainer pokemonTrainerCreate(char* name, Pokemon initial_pokemon,
int max_num_local, int max_num_remote)
{
PokemonTrainer trainer = malloc(sizeof(PokemonTrainer));
if ((name == NULL) || (initial_pokemon == NULL) || (trainer == NULL) ||
(max_num_local < 0) || (max_num_remote < 0))
return NULL;
char tmp_name[strlen(name)];
strcpy(tmp_name, name);
trainer->name = tmp_name;
trainer->max_num_local = max_num_local;
trainer->max_num_remote = max_num_remote;
trainer->pokemons_local = malloc(sizeof(Pokemon)
trainer->max_num_local);
trainer->pokemons_remote = malloc(sizeof(Pokemon)
trainer->max_num_remote);
if (trainer->pokemons_remote == NULL) {
free(trainer->pokemons_local);
return NULL;
} else if (trainer->pokemons_local == NULL) {
free(trainer->pokemons_remote);
return NULL;
}
trainer->pokemons_local[0] = pokemonCopy(initial_pokemon);
trainer->curr_num_local = 1;
trainer->curr_num_remote = 0;
return trainer;
}
void pokemonTrainerDestroy(PokemonTrainer trainer)
{
if (trainer == NULL)
return;
if (trainer->curr_num_local > 0)
for (int i = trainer->curr_num_local - 1; i >= 0; i--)
pokemonDestroy(trainer->pokemons_local[i]);
if (trainer->curr_num_remote > 0)
for (int i = trainer->curr_num_remote - 1; i >= 0; i--)
pokemonDestroy(trainer->pokemons_remote[i]);
free (trainer); // here it's crashed
}
It is during the execution of free() in the stack that I am getting a "No source available for "ntdll!RtlpNtEnumerateSubKey() at 0x77cf04e5" error.

PokemonTrainer trainer = malloc(sizeof(PokemonTrainer)); is unlikely to work properly since you're allocating the size of the pointer, not the real data.
You won't have enough storage => undefined behaviour happens, and for you it happens when freeing the memory (corrupt memory list)
I would do this:
PokemonTrainer trainer = malloc(sizeof(*PokemonTrainer));
so the sizeof takes the size of the structure pointed by PokemonTrainer.
EDIT: for completeness, BLUEPIXY suggests that you've missing 1 byte here (because of null-termination char):
char tmp_name[strlen(name)];
strcpy(tmp_name, name);
and moreover this allocated space is temporary, so I'd suggest:
char *tmp_name = strdup(name);
which will allocate the correct size and performs a dynamic allocation that stays valid even after returning from the routine.

Related

asprint memory leak need help understand where leak is coming from and possible fixes

Note: I did call this function and free it main but valgrind still shows error.
This code basically takes in a singly linked-list with two data coeff and exp. This is basically converting a polynomial store in a linked list converted to readable string. I looking to have it dynamic allocated.
char *Poly_to_string(const Polynomial *p)
{
char *x = malloc(1);
int size;
while (p != NULL)
{
if((p->exp != 0) && (p->exp != 1))
{
size = asprintf(&x, "%s%dx^%d + ", x, p->coeff, p->exp);
if (size == -1)
{
exit(-1);
}
}
else if(p->exp == 1)
{
size = asprintf(&x, "%s%dx + ", x, p->coeff);
if (size == -1)
{
exit(-1);
}
}
else if(!p->exp)
{
size = asprintf(&x, "%s%d + ", x, p->coeff);
if (size == -1)
{
exit(-1);
}
}
p = p->next;
}
x[strlen(x) - 3] = '\0';
return x;
}
From the Linux asprintf() man page (bolding mine):
DESCRIPTION
The functions asprintf() and vasprintf() are analogs of
sprintf(3) and vsprintf(3), except that they allocate a string
large enough to hold the output including the terminating null
byte ('\0'), and return a pointer to it via the first argument.
This pointer should be passed to free(3) to release the allocated
storage when it is no longer needed.
RETURN VALUE
When successful, these functions return the number of bytes
printed, just like sprintf(3). If memory allocation wasn't
possible, or some other error occurs, these functions will return
-1, and the contents of strp are undefined.
This line is wrong:
char *x = malloc(1);
It should just be
char *x;
because if asprintf() works, it will overwrite the contents of x and cause the memory allocated in char *x = malloc(1); to be leaked.
EDIT
The looping also needs to be addressed, as you're trying to grow the string:
char *Poly_to_string(const Polynomial *p)
{
// start with an empty string that can be free()'d
// (if you don't have strdup() use malloc() and strcpy())
char *x = strdup("");
int size;
while (p != NULL)
{
// save the old malloc()'d value so it can be free()'d
char *oldValue = x;
if((p->exp != 0) && (p->exp != 1))
{
size = asprintf(&x, "%s%dx^%d + ", x, p->coeff, p->exp);
if (size == -1)
{
exit(-1);
}
}
else if(p->exp == 1)
{
size = asprintf(&x, "%s%dx + ", x, p->coeff);
if (size == -1)
{
exit(-1);
}
}
else if(!p->exp)
{
size = asprintf(&x, "%s%d + ", x, p->coeff);
if (size == -1)
{
exit(-1);
}
}
// free() the old value
free(oldValue);
p = p->next;
}
x[strlen(x) - 3] = '\0';
return x;
}
There are other ways to do this without the initial char *x = strdup(""); but the code then becomes a lot more complex.
You're not deallocating variable x

free pointers not working even though they're allocated

I have two pointers in my program which freeing them doesn't work, I don't get an error of any sort, just an error sound from visual studio..
The program runs perfectly fine if I don't free them (but I know I must do that).
This is my code with everything that uses those two pointers, hopefully you'll help me.
void gameProcess(char *word, int len)
{
int i, letterExist, life = 7, temp;
char *pGuess, *bank, c;
if (!(bank = (char*)malloc(N)))
printf("Error!! Allocated memory failure!");
bank[N] = '\0';
if (!(pGuess = (char*)malloc(len)))
printf("Error!! Allocated memory failure!");
pGuess[len] = '\0';
guessVisual(pGuess);
while (life > 0 && len > 0)
{
letterExist = 0;
printf("\n\nEnter your guess please:\n");
c = guessInterface(word, pGuess, bank);
letterExist = checkIfExist(word, c, len);
temp = replaceIfExist(word, c, pGuess);
if (letterExist > 0)
len = rightGuess(pGuess, len, temp);
else
life = wrongGuess(life);
if (len == 0)
win();
if (life == 0)
lose();
}
free(pGuess);//***************
free(bank);//***************
}
Thank you!
If any other info is needed, let me know.

realloc: invalid checksum for freed object

I have an error using realloc to replace malloc.
This code below runs OK on my computer.
int vector_grow(Vector* vec) {
unsigned long newcap;
int * newarr;
if (0 == vec->cap) {
vec->arr = (int*)malloc(START_CAPACITY * sizeof(*vec->arr));
if (NULL == vec->arr)
return -1;
vec->cap = START_CAPACITY;
return 0;
}
newarr = malloc (newcap * sizeof(*vec->arr));
if (NULL == newarr)
return -1;
memcpy (newarr, vec->arr, vec->len * sizeof(*vec->arr));
free (vec->arr);
vec->arr = newarr;
vec->cap = newcap;
return 0;
}
I want to change the malloc to realloc, but the error occurs.
int vector_grow(Vector* vec) {
unsigned long newcap;
if (0 == vec->cap) {
vec->arr = (int*)malloc(START_CAPACITY * sizeof(*vec->arr));
if (NULL == vec->arr)
return -1;
vec->cap = START_CAPACITY;
return 0;
}
newcap = 2 * vec->cap;
if ((vec->arr = (int*)realloc(vec->arr, newcap * sizeof(int))) == NULL)
return -1;
return 0;
}
It says
malloc: *** error for object 0x7fca64c02598: incorrect checksum for freed object - object was probably modified after being freed.
I don't know any difference between those two snippets of code, if you know what causes the error, please tell me! Thank you very much!
Bug in missing vec->cap = in updated code certainly contribute to various calls to malloc() and calling code's misuse of data.
int vector_grow(Vector* vec) {
unsigned long newcap;
if (0 == vec->cap) {
... // not important to show the bug
}
newcap = 2 * vec->cap;
if ((vec->arr = (int*)realloc(vec->arr, newcap * sizeof(int))) == NULL)
return -1;
// Add missing update
vec->cap = newcap;
return 0;
}
Also better to test for allocation success
void *p = realloc(vec->arr, sizeof *(vec->arr) * newcap);
if (p == NULL) {
return -1;
}
vec->arr = p;
vec->cap = newcap;
The only scenario where I can imagine such error message is when you actually modify the pointer, for example
int *x = malloc(2 * sizeof *x);
if (x != NULL) {
x = x + 1;
free(x);
}
The pointer that MUST be passed to free() MUST had been returned by malloc()/calloc()/realloc(), passing any other pointer including a pointer to the same data but at a different position like x in the example above is undefined behavior.

Memory Leaking - C

In the same file I have two routines. The first will store some bytes from one file. The other will give this information to routines that will process that information.
boolean
adin_memory(char* buffer, int size_chunck, int end_flag){
real_data=(SP16 *)malloc(size_chunck); //real_data -->global
memcpy(&(real_data[0]),&(buffer[0]),size_chunck);
pos_write += size_chunck;
global_size = size_chunck;
global_end_flag = end_flag;
//end_flag = 1 --> end of Stream
//end_flag = 0 --> Streaming
return TRUE;
}
To prevent the possibility of leaking I am using malloc. But this routine is called several times. So, after some repetitions of adin_memory and adin_read (where will be free), I think the memory starts to fragment (I can see a leak with the size of the input file in task manager - increment of RAM). Is that right? How can I prevent this? To see this leak I put one breakpoint at the beginning and at the end of adin_memory an look at task manager.
int
adin_read(SP16 *buf, int sampnum)
{
FILE *fp;
int cnt = 0;
fp = gfp;
//(.......)
if(global_end_flag == 1 || pos_write == pos_read){ return -1;}
for(i = pos_read/sizeof(SP16); i <= sampnum; i++){
if(i >= pos_write/sizeof(SP16)) {
cnt = i;
//(....)
break;
}
buf[i] = real_data[i];
}
pos_write = 0;
//(....)
free(real_data);
return cnt;
}
int
adin_read(SP16 *buf, int sampnum)
{
FILE *fp;
int cnt = 0;
fp = gfp;
//(.......)
if(global_end_flag == 1 || pos_write == pos_read){
/* Leak is possibly here. You return without freeing.
Ensure free is called here also. And it is good practice to
make the freed pointer point to NULL so you can check and
avoid double free problems. */
return -1;
}
for(i = pos_read/sizeof(SP16); i <= sampnum; i++){
if(i >= pos_write/sizeof(SP16)) {
cnt = i;
//(....)
break;
}
buf[i] = real_data[i];
}
pos_write = 0;
//(....)
free(real_data);
return cnt;
}
Difficult to say without further context describing how you use these functions but...
Every time you call your adin_memory() function it will allocate some memory (via a call to malloc) and then set real_data to point to that newly allocated memory.
If real_data was already pointing to some allocated memory then you just leaked it.
So if your main program calls adin_memory() three times and then calls adin_read() then you will leak two blocks of memory and only free the last one.
Change
if(global_end_flag == 1 || pos_write == pos_read){ return -1;}
To
if(global_end_flag == 1 || pos_write == pos_read)
{
free(real_data);
return -1;
}
The problem was indeed in the successive malloc/free (wich cause memory fragmentation). After removed I create a global pointer to the incoming bytes. And make the memcpy in the adin_read()
int adin_read(SP16 *buf, int sampnum)
{
int i;
int cnt = 0;
if(global_end_flag == 1 || pos_write == pos_read){return -1}
memcpy(buf,global_buffer,global_size);
cnt = global_size/sizeof(SP16);
pos_write = 0;
pos_read = 0;
//(....)
return cnt;
}
And then:
boolean
adin_memory(char* buffer, int size_chunck, int end_flag){
pos_write += size_chunck;
global_size = size_chunck;
global_end_flag = end_flag;
global_buffer = buffer;
return TRUE;
}

private memory usage keep raising using c in Linux

I'm writing a service in Linux using c, so I need to keep the memory usage stable.
But after tracing a day, the memory raise.
If I monitor from the System Monitor in Linux, it raise 1M and the mem%(0 -> 0.1).
In pmap command, it raise 1M, too.
I have use valgrind to check if there are any memory leak, and it report none if I run once.
If I start the service and use valgrind, it will report that I free invalid pointer.
So, I think it should have something to do about my pointer.
struct list {
int no;
BYTE parm[SLEN];
struct list *next;
};
struct list *memory_current;
struct list *memory_head;
struct list *memory_prev;
int getMemoryUsage(int sendCmd) {
pthread_mutex_lock(&lock);
FILE *fp = NULL;
BYTE buffer[10] = "";
BYTE memorys[10] = "";
int flag = 0;
TRY {
if ((fp = popen("free_data=$(free -m | grep Mem);total=$(echo $free_data | cut -f2 -d' ');"
"free_data=$(free -m | grep 'buffers/cache');buffers=$(echo $free_data | cut -f3 -d' ');echo $(($buffers*100/$total))", "r")) == NULL) {
THROW(CMD_NOT_FND);
}
else {
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
strcat(memorys, buffer);
memory_current = (struct list *)malloc(sizeof(struct list));
if (memory_current == NULL) {
THROW(MALLOC_ERROR);
}
memory_current->next = NULL;
strncpy(memory_current->parm, buffer, SLEN -1);
memory_current->parm[SLEN -1] = '\0';
if (memory_head == NULL)
memory_head = memory_current;
else
memory_prev->next = memory_current;
memory_prev = memory_current;
memset(buffer, 0, sizeof(buffer));
flag = 1;
}
if (flag == 0)
THROW(CMD_NOT_FND);
}
}
CATCH (CMD_NOT_FND) {
memorys[0] = 'n';
memorys[1] = '/';
memorys[2] = 'a';
printf("Memory Usage % : %s\n", memorys);
printLog("Memory Usage % ->", memorys);
}
CATCH (MALLOC_ERROR) {
memorys[0] = 'n';
memorys[1] = '/';
memorys[2] = 'a';
printf("Memory Usage malloc error : %s\n", memorys);
printLog("Memory Usage malloc error ->", memorys);
}
FINALLY {
pclose(fp);
// printf("Memory Usage % : %s\n", memorys);
// printf("Memory Usage length %d\n", strlen(memorys));
}
ETRY;
if (sendCmd == 1) {
if (flag != 0) {
memory_current = memory_head;
int totalMemory = 0;
int count = 0;
int avg = 0;
int perc = 0;
BYTE avg_memory[10] = "";
while (memory_current != NULL) {
sscanf(memory_current->parm, "%d", &perc);
totalMemory += perc;
memory_current = memory_current->next;
count++;
}
avg = totalMemory / count;
snprintf(avg_memory, sizeof(avg_memory), "%d", avg); ;
strcat(avg_memory, ";");
printf("Memory Usage % : %s\n", avg_memory);
printLog("Memory Usage % ->", avg_memory);
// free linked list
memory_current = memory_head;
while (memory_current != NULL) {
memory_prev = memory_current;
memory_current = memory_current->next;
free(memory_prev);
memory_prev = NULL; //fix dangling
}
head_memory = NULL; //fix dangling
current_memory = NULL; //fix dangling
}
}
pthread_mutex_unlock(&lock);
return 0;
}
I have the global pointer to keep record the memory usage in a timer, and I will use the result and clear the list in a interval of time.
I use the same way to use in other function and the memory usage is fine, but the pointers are local and will free at the end.
Could you please help to advice or pointer out what is wrong about my pointer usage.
Thanks.
[Update]
I found that this might be a dangling pointer, so I set the pointer to NULL after the free.
So far the memory won't raise, but I'll keep watching it for more days.
Solved
The memory won't raise again, so I guess it's the dangling pointer issue.
memory_current, memory_head and memory_prev were not initialized to NULL.
you check:
if (memory_head == NULL)
when memory_head was not initialized, therefore you maybe loose some memory allocations
also look like they should be local variables, not global.

Resources