attempt to free memory causes error - c

I have declared the following struct:
typedef struct _RECOGNITIONRESULT {
int begin_time_ms, end_time_ms;
char* word;
} RECOGNITIONRESULT;
There is a method that creates an array of RECOGNITIONRESULT and fills it (for test purposes only):
void test_realloc(RECOGNITIONRESULT** p, int count){
int i;
*p = (RECOGNITIONRESULT *)realloc(*p, count * sizeof(RECOGNITIONRESULT));
for (i = 0; i < count; i++){
(*p)[i].begin_time_ms = 2*i;
(*p)[i].end_time_ms = 2*i+1;
(*p)[i].word=(char *) malloc ( (strlen("hello"+1) * sizeof(char ) ));
strcpy((*p)[i].word,"hello");
}
}
The method to free memory is:
void free_realloc(RECOGNITIONRESULT* p, int count){
int i = 0;
if(p != NULL){
if (count > 0){
for (i = 0; i < count; i++){
free(p[i].word); //THE PROBLEM IS HERE.
}
}
free(p);
}
}
The main method calls those methods like this:
int main(int argc, char** argv)
{
int count = 10;
RECOGNITIONRESULT *p = NULL;
test_realloc(&p,count);
free_realloc(p,count);
return 0;
}
Then if I try to free the memory allocated for "word", I get the following error:
HEAP CORRUPTION DETECTED: after normal block (#63) at 0x003D31D8.
CRT detected that the application wrote to memory after end of heap buffer.
Using the debugger I've discovered that the crash occurs when calling free(p[i].word);
What am I doing wrong? How can I free he memory for the strings?

The problem is in your allocation of memory for word. strlen("hello"+1) should be strlen("hello")+1.

Since you appear to allocate a whole array of structures in one strike
RECOGNITIONRESULT **p;
*p = (RECOGNITIONRESULT *)realloc(*p, count * sizeof(RECOGNITIONRESULT));
you can free them in one call to free() as well :
void free_realloc(RECOGNITIONRESULT *p, int count){
free(p);
}
And the strlen("hello"+1) is also wrong, as detected by Chowlett.

Related

Error in `<unknown>': corrupted double-linked list: 0x011eb8e0 happens Occasionally when calling free

I have a problem with free.
I test my code in online compiler but everything is OK. However in my device (which is a POS) it rises exception when calling free. It frees two of 4 variables and then rise exception.
My real Code for device:
char **MenuItems = malloc (MAX_PACKETS * sizeof(char *));
struct packetInfos * packets = (struct packetInfos *)malloc(sizeof(struct packetInfos)*MAX_PACKETS);
size = getPacketNames(groupId,packets,MenuItems);
...
...
...
TRACE(("====size %d",size));
for(;i<size;i++) {
TRACE(("====%d=",i,MenuItems[i]));
free(MenuItems[i]);
}
free(MenuItems);
gives me:
[src/menu.c][NetChargeMenu_L3][1637]>>>====size 4
[src/menu.c][NetChargeMenu_L3][1639]>>>===counter=0 address=34259480
[src/menu.c][NetChargeMenu_L3][1639]>>>===counter=1 address=34260528
Sometimes it frees all variables but give me the following error and freeze everything:
Error in `<unknown>': corrupted double-linked list: 0x011eb8e0
my program is something like this
#include <stdio.h>
#include <stdlib.h>
#define MAX 16
int getPacketNames(char **names){
int limit = 4;
int i = 0;
for(i=0;i<MAX;i++) {
if(i==limit)
break;
names[i] = malloc(64);
sprintf(names[i],"random text %d",i);
}
return i;
}
int main()
{
printf("Hello World");
int i=0;
int size=0;
char **MenuItems = malloc (MAX * sizeof(char *));
size = getPacketNames(MenuItems);
// do something
for(i=0;i<size;i++) {
free(MenuItems[i]);
}
free(MenuItems);
return 0;
}
I read this post (What does 'corrupted double-linked list' mean) by cannot find a useful hint for my code in C.
Thanks for any hints.
The cause is for malloc memory not for free it. I used fixed length in allocation! Before I used dynamic size for allocating. However allocating dynamic size memory must not be a problem, but using fixed size allocation maybe solve other problems such my problem.
My previous code (With problem when free):
struct packetInfos{
int id;
char name[64];
long amount;
};
void getOperatorNames(char *names[]) {
int i=0;
for(; i<MAX; i++) {
sprintf(packets[i].name, "%s", sqlite3_column_text(stmt, 2));
names[i] = malloc(strlen(packets[i].name) + 1); // the cause of problem in free
strcpy(names[i], op[i].fname);
}
}
My current code (Without problem):
void getOperatorNames(char *names[]) {
int i=0;
for(; i<MAX; i++) {
sprintf(packets[i].name, "%s", sqlite3_column_text(stmt, 2));
names[i] = malloc(64);
strcpy(names[i], op[i].fname);
}
}

Segmentation fault (core dumped) in C program

I have the following program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 255
char * decrypt(char *p, int key){
char *tmp;
for(int i = 0; p[i] != '\0'; i++){
tmp[i] = p[i]-key;
}
return tmp;
}
int main(void){
printf("Hallo Welt!");
printf("%s\n", decrypt("ibmmp", 1));
return EXIT_SUCCESS;
}
When I compile it with gcc -Wall i get the Warning tmp could get uninitialized in this function [-Wmaybe-uninitialized] tmp[i] = p[i]-key(translated from german) and segmentation fault (core dumped) ./crypto when i run it
What is causing that error?
I know this quesion has been asked many times, but i could not fix this warning, because other people had different sourcecodes and i couldn't adapt it to my problem.
You need to allocate 'tmp' and then, keeping with good 'c' coding, check that the allocation was successful. I assume you have MAX defined so you can set an upper-bound on the length of your string, so I use that below. If MAX is intended to be the number of characters without a null, then you need to 'malloc(MAX +1)'. If it is intended to include NULL, then just leave the code as defined below. You also want to decide what to return on failure of the malloc. I return NULL, but you may want to do something different depending on your needs.
Also be aware, that this function is returning allocated memory, so someone needs to free it so you aren't leaking memory.
char * decrypt(char *p, int key){
char *tmp;
tmp = (char *) malloc(MAX);
if(!tmp)
return NULL;
for(int i = 0; p[i] != '\0'; i++){
tmp[i] = p[i]-key;
}
return tmp;
}
Allocate memory for tmp before using it. Make sure you null-terminate the string before returning it.
// Make the input a const string.
// char * decrypt(char *p, int key){
char * decrypt(char const* p, int key){
char *tmp = malloc(strlen(p) + 1); // Allocate memory
int i = 0;
for( ; p[i] != '\0'; i++){
tmp[i] = p[i]-key;
}
tmp[i] = '\0'; // null terminate.
return tmp;
}
Make sure you deallocate the memory. Just using
printf("%s\n", decrypt("ibmmp", 1));
will result in a memory leak.
int main(void){
printf("Hallo Welt!");
char* dec = decrypt("ibmmp", 1)
printf("%s\n", dec);
free(dec); // Deallocate memory.
return EXIT_SUCCESS;
}

Segfault in my csv_loader() function

I'm trying to write a csv parser in C, but every time I get a segfault in this function. I don't know how to fix it.
char*** csv_loader(char *filename){
FILE* file_xx;
file_xx = fopen(filename, "r");
if(file_xx==NULL){
printf("Failed to open File, no such file or directory!\n");
return 0;
}
int c_=0;
int **linenumbers;
int l=lines(filename);
linenumbers=malloc(sizeof(int)*l);
char*** loaded_csv;
int counter_line=0;
int counter_row=0;
loaded_csv=malloc(sizeof(char **) *l);
loaded_csv[0][0]=malloc(getfirstcolumn(filename)*sizeof(char)+2);
if(NULL==loaded_csv){
printf("Failed to initialize 'char** loaded_csv'!\n");
return 0;
}
int c_c=0;
int *cm=get_column_map(filename);
for(c_c=0;c_c<l;c_c++){
loaded_csv[c_c]=malloc(sizeof(char *)*cm[c_c]);
}
while(c_!=EOF){
c_=getc(file_xx);
if(c_=='\n'){
linenumbers[counter_line][cm[counter_line]]=counter_row+2;
loaded_csv[counter_line][cm[counter_line]]=malloc(counter_row*sizeof(char));
if(NULL == loaded_csv[counter_line][cm[counter_line]]){
return 0;
}
loaded_csv[counter_line][counter_row]='\0';
counter_row=0;
counter_line++;
}else{
if(c_==','){
counter_row=0;
}else{
counter_row++;
}
}
}
fclose(file_xx);
FILE*fgetsread;
fgetsread=fopen(filename, "r");
int ident, ident_c;
for(ident=0;ident<l;ident++){
for(ident_c=0;ident_c<cm[ident];ident_c++){
fgets(loaded_csv[ident][ident_c], linenumbers[ident][ident_c], fgetsread);
loaded_csv[ident][ident_c][linenumbers[ident][ident_c]-2]='\0';
}
}
fclose(fgetsread);
free(linenumbers);
return loaded_csv;
}
The Debugger says it's this line:
loaded_csv[0][0]=malloc(getfirstcolumn(filename)*sizeof(char)+2);
Does anyone know what's the bug? I'm yet new to C and anyway try to understand the malloc thing...
PS: the other functions are here: http://pastebin.com/VQZ4d5UU
So, you've allocated space on the line right before:
loaded_csv=malloc(sizeof(char **) *l);
That is fine and dandy, but loaded_csv[0] isn't yet initialized to somewhere you own. So, when you do the following line
loaded_csv[0][0]=malloc(getfirstcolumn(filename)*sizeof(char)+2);
you are trying to set a variable located in some random location (wherever loaded_csv[0] happens to be right then).
If you want to touch loaded_csv[0][0], you'll have to make sure that loaded_csv[0] is pointing to valid memory first (probably by allocating memory for it via malloc before you allocate something for loaded_csv[0][0].)
You've got a problem with this line:
loaded_csv[0][0]=malloc(getfirstcolumn(filename)*sizeof(char)+2);
Which suggest you are not allocating and initializing loaded_csv[0][0] right.
Here is an example of how to initialize and use a char ***var:
#include <windows.h>
#include <ansi_c.h>
char *** Create3D(int p, int c, int r);
int main(void)
{
char ***pppVar;
pppVar = Create3D(10,10,10);
//test pppVar;
strcpy(pppVar[0][0], "asdfasf");
strcpy(pppVar[0][1], "the ball");
return 0;
}
char *** Create3D(int p, int c, int r)
{
char *space;
char ***arr;
int x,y;
space = calloc (p*c*r*sizeof(char),sizeof(char));
arr = calloc(p * sizeof(char **), sizeof(char));
for(x = 0; x < p; x++)
{
arr[x] = calloc(c * sizeof(char *),sizeof(char));
for(y = 0; y < c; y++)
{
arr[x][y] = ((char *)space + (x*(c*r) + y*r));
}
}
return arr;
}
Be sure to keep track of and free(x) appropriately.

Setting a double pointer array

I know there are a lot of double pointer questions, but I couldn't find one that pertained to starting an array.
In the code below, I can set pointers in main by ptrs[0] = &array[0];, but the code halts when enqueue() calls *queue[i] = p;. Why is that? I don't know if it matters, but ptrs[] is not initialized.
#define QUEUE_LEN 5
int *ptrs[5];
int array[5] = {1,2,3,4,5};
void enqueue(int *p, int **queue) {
int i = 0;
int *tmp;
// Find correct slot
while (*queue && *queue[i] >= *p) {
i++;
}
// Error no free slots
if (i == QUEUE_LEN) {
printf("No free slots.\r\n");
return;
}
// Insert process
if (!*queue) {
*queue[i] = p;
return;
}
else {
tmp = *queue[i];
*queue[i] = p;
}
// Increment the other processes
return;
}
int main(int argc, char** argv) {
int i;
for (i=0; i<5; i++) {
enqueue(&array[i], ptrs);
}
for (i=0; i<QUEUE_LEN; i++)
printf("%d\n", *(ptrs[i]));
return 0;
}
After first loop, i will remain zero. Here:
if (!*queue) {
*queue[i] = p;
return;
}
You check, that *queue is 0 and dereference it as well. It is UB.
PS. Btw, this:
*queue[i] = p;
Will not compiles, since *queue[i] has type int, but p has type int*.
// Find correct slot
while (*queue && *queue[i] >= *p) {
i++;
}
This will access some random memory address taken from uninitialized ptrs value.
Your check for *queue != 0 is not enough, you need to initialize array with zeores as:
int *ptrs[5] = {0};
And you still need to allocate memory you are attempting to write later when inserting.

Allocating and Freeing pointer to pointer

I'm attempting to pass a pointer to a pointer (char**) into a function that will initialize it, and then pass it into another function that will free the memory, however I'm getting seg faults on the freeing which leads me to believe my allocation is going wrong.
Valgrind is reporting use of uninitalized value at this line. tmp[i] is pointing to 0x0.
if(tmp[i]) free((char*)tmp[i]);
Here is the code (this is only test code)
void
alloc_strings(char ***test, int count)
{
char **tmp = *test;
tmp = malloc(count * sizeof(char*));
int i;
for(i = 0; i < count; i++) {
tmp[i] = malloc(6);
strcpy(tmp[i],"Hello");
}
}
void
free_strings(char ***test, int count)
{
char **tmp = *test;
int i;
for(i = 0; i < count; i++) {
if(tmp[i]) free((char*)tmp[i]);
}
if(tmp)
free(tmp);
}
And the invocation:
int
main(int argc, char **argv)
{
char **test;
alloc_strings(&test, 10);
free_strings(&test, 10);
return 0;
}
I have been playing around with this for a while, reading up on pointers etc however can't get my head around the issue. Any thoughts greatly appreciated!
You need to assign to *test, not to assign from it. How about:
void
alloc_strings(char ***test, int count)
{
char **tmp = malloc(count * sizeof *tmp);
/*...*/
*test = tmp;
}
In the code example,
alloc_strings(char ***test, int count)
{
char **tmp = *test;
*test should have some space to store a pointer to char ** which currently is not allocated. Hence, if the example is as this
char** array[1];
alloc_strings(&array[0], 7);
I feel that the code will work.

Resources