473,395 Members | 1,972 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Program Crashing when freeing memory

Hi all,
I am not able to figure out why the following program fails. Hope this
long program does not irritate you.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define K_TITLE_LEN 14
#define K_MAX_PLMS_ENTRIES 2000
#define K_SUMMARY_TITLE_LEN 18
typedef struct
{
int desc_code;
int meas_num;
char title[K_SUMMARY_TITLE_LEN];
}cond_summ_data_t;
typedef struct
{
int count;
cond_summ_data_t data[K_MAX_PLMS_ENTRIES];

}cond_summ_t;
void listGetCondSumTitle(/* IN */ const cond_summ_t *plms_table,
/* IN */ int num_meas,
/* IN */ int num_desc,
/* IN */ const int *meas_num,
/* IN */ int *desc_code,
/* OUT */char title[][K_TITLE_LEN])
{
int plms_ind = 0;
int meas_ind = 0;
int desc_ind = 0;
typedef char temp_title_t[K_TITLE_LEN];
temp_title_t **temp_title;

temp_title = malloc(num_desc * sizeof(temp_title_t *));
for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
temp_title[desc_ind] = malloc(num_meas * sizeof(temp_title));
}

for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
for (meas_ind = 0; meas_ind < num_meas; meas_ind++)
{
strcpy(temp_title[desc_ind][meas_ind]," ");
}
}

/*For each plot meas entry*/
for (plms_ind = 0; plms_ind < plms_table->count; plms_ind++)
{
/*Until no measurement number left in meas_num*/
for (meas_ind = 0; meas_ind < num_meas; meas_ind++)
{
/*Compare with the measurement number of plotmeas meas_no*/
if ( meas_num[meas_ind] ==
(plms_table->data[plms_ind]).meas_num )
{
/*If Matches*/
/*Compare with desc code in plotmeas*/
for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
/*Compare with desc code in plotmeas.*/
if (desc_code[desc_ind] == (plms_table

->data[plms_ind]).desc_code)
{
/*If matches get the title and store in
temp_title*/
strcpy(
temp_title[desc_ind][meas_ind],
(plms_table->data[plms_ind]).title);
break;
}
}

}
}
}
for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
for (meas_ind = 0; meas_ind < num_meas; meas_ind++)
{
printf("temp_title[%d][%d] = %7s ",desc_ind, meas_ind,
temp_title[desc_ind][meas_ind]);
}
printf("\n");
}

for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
free(temp_title[desc_ind]); /*Program crashes here*/
}
free(temp_title);
}

int main()
{
cond_summ_t plms_table;
int num_meas=4;
int num_desc=7;
int desc_code[7] = {2,3,4,5,7,8,10};
int meas_num[4]={1000,2000,3000,4000};
char title[30][K_TITLE_LEN];

plms_table.count = 30;

plms_table.data[0].desc_code=2;
plms_table.data[0].meas_num=100;
strcpy(plms_table.data[0].title,"Two");
plms_table.data[1].desc_code=3;
plms_table.data[1].meas_num=100;
strcpy(plms_table.data[1].title,"Two");
plms_table.data[2].desc_code=3;
plms_table.data[2].meas_num=1000;
strcpy(plms_table.data[2].title,"Three");
plms_table.data[3].desc_code=7;
plms_table.data[3].meas_num=1000;
strcpy(plms_table.data[3].title,"Seven");
plms_table.data[4].desc_code=3;
plms_table.data[4].meas_num=2000;
strcpy(plms_table.data[2].title,"Three");
plms_table.data[5].desc_code=7;
plms_table.data[5].meas_num=2000;
strcpy(plms_table.data[3].title,"2-Seven");

plms_table.data[6].meas_num=4000;
strcpy(plms_table.data[6].title,"Three");
plms_table.data[7].desc_code=10;
plms_table.data[7].meas_num=4000;
strcpy(plms_table.data[7].title,"Ten");

listGetCondSumTitle(&plms_table,
num_meas,
num_desc,
meas_num,
desc_code,
title);
return 0;
}
Thanks for help

Dec 1 '05 #1
4 1435

va******@rediffmail.com wrote:
Hi all,
I am not able to figure out why the following program fails. Hope this
long program does not irritate you.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define K_TITLE_LEN 14
#define K_MAX_PLMS_ENTRIES 2000
#define K_SUMMARY_TITLE_LEN 18
typedef struct
{
int desc_code;
int meas_num;
char title[K_SUMMARY_TITLE_LEN];
}cond_summ_data_t;
typedef struct
{
int count;
cond_summ_data_t data[K_MAX_PLMS_ENTRIES];

}cond_summ_t;
void listGetCondSumTitle(/* IN */ const cond_summ_t *plms_table,
/* IN */ int num_meas,
/* IN */ int num_desc,
/* IN */ const int *meas_num,
/* IN */ int *desc_code,
/* OUT */char title[][K_TITLE_LEN])
{
int plms_ind = 0;
int meas_ind = 0;
int desc_ind = 0;
typedef char temp_title_t[K_TITLE_LEN];
temp_title_t **temp_title;

temp_title = malloc(num_desc * sizeof(temp_title_t *)); I think here using explicit casting "(temp_title_t **)malloc(...)" is
a better way. for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
temp_title[desc_ind] = malloc(num_meas * sizeof(temp_title));
} Here you made a small mistake, inside the bracket of sizeof it should
be temp_title_t, and the same as above, explicit casting "(temp_title_t
*)malloc(...)" might be better.


I used VC.Net to test the file, as currently I do not have a gcc
environment. Excuse me for my English... It's not my native tongue.

Dec 1 '05 #2
Yangqing, JIA said:

va******@rediffmail.com wrote:
temp_title = malloc(num_desc * sizeof(temp_title_t *));

I think here using explicit casting "(temp_title_t **)malloc(...)" is
a better way.


Why? It's a useless cast. An implicit conversion is supplied. If you're
going to suggest an improvement, suggest:

temp_title = malloc(num_desc * sizeof *temp_title);

for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
temp_title[desc_ind] = malloc(num_meas * sizeof(temp_title));
}

Here you made a small mistake, inside the bracket of sizeof it should
be temp_title_t, and the same as above, explicit casting "(temp_title_t
*)malloc(...)" might be better.


Forget the useless cast. The best way to do this call is:

temp_title[desc_ind] = malloc(num_meas * sizeof *temp_title[desc_ind]);

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Dec 1 '05 #3
"Yangqing, JIA" <ji*****@gmail.com> writes:
va******@rediffmail.com wrote:
temp_title = malloc(num_desc * sizeof(temp_title_t *));

I think here using explicit casting "(temp_title_t **)malloc(...)" is
a better way.


Why do you think that? My personal preferences is to avoid casts as
much as possible, and when not possible to avoid them I usually
try to find some other solution first.

Here a cast is totally meaningless, since the void* returned by
malloc is automagically converted to the correct pointer type.

Could you please elaborate on why you think the cast is a better
way?

The prefered way in comp.lang.c is:

ptr = malloc(count * sizeof *ptr);
for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
temp_title[desc_ind] = malloc(num_meas * sizeof(temp_title));
}

Here you made a small mistake, inside the bracket of sizeof it should
be temp_title_t, and the same as above, explicit casting "(temp_title_t
*)malloc(...)" might be better.


You are correct. The bug is that the amount of memory allocated is not
enough, and later in the code a strcpy writes out of bounds because of
this.

This would of course not have happened if the original poster had used
the style I proposed:

temp_title[desc_ind] = malloc(num_meas * sizeof *temp_title[desc_ind]);

/Niklas Norrthon
Dec 1 '05 #4
On 30 Nov 2005 20:51:39 -0800, va******@rediffmail.com wrote:
Hi all,
I am not able to figure out why the following program fails. Hope this
long program does not irritate you.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define K_TITLE_LEN 14
#define K_MAX_PLMS_ENTRIES 2000
#define K_SUMMARY_TITLE_LEN 18
typedef struct
{
int desc_code;
int meas_num;
char title[K_SUMMARY_TITLE_LEN];
}cond_summ_data_t;
typedef struct
{
int count;
cond_summ_data_t data[K_MAX_PLMS_ENTRIES];

}cond_summ_t;
void listGetCondSumTitle(/* IN */ const cond_summ_t *plms_table,
/* IN */ int num_meas,
/* IN */ int num_desc,
/* IN */ const int *meas_num,
/* IN */ int *desc_code,
/* OUT */char title[][K_TITLE_LEN])
{
int plms_ind = 0;
int meas_ind = 0;
int desc_ind = 0;
typedef char temp_title_t[K_TITLE_LEN];
temp_title_t **temp_title;

temp_title = malloc(num_desc * sizeof(temp_title_t *));
for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
temp_title[desc_ind] = malloc(num_meas * sizeof(temp_title));
As others have pointed out, you are using the wrong sizeof. temp_title
is a pointer. Odds are its size is 4. So you have allocated
num_meas*4 bytes.
}

for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
for (meas_ind = 0; meas_ind < num_meas; meas_ind++)
{
strcpy(temp_title[desc_ind][meas_ind]," ");
Here you lie to the compiler. temp_title is a pointer to pointer to
array of 18 char. temp_title[...] is a pointer to such an array.
temp_title[...][...] is such an array. But you did not allocate space
for num_meas such arrays. You under-allocated by 75%. At some point,
strcpy will begin to overflow your allocated area. This is undefined
behavior. One common outcome of doing this is that you destroy the
data malloc uses to keep track of allocated memory.
}
}

/*For each plot meas entry*/
for (plms_ind = 0; plms_ind < plms_table->count; plms_ind++)
{
/*Until no measurement number left in meas_num*/
for (meas_ind = 0; meas_ind < num_meas; meas_ind++)
{
/*Compare with the measurement number of plotmeas meas_no*/
if ( meas_num[meas_ind] ==
(plms_table->data[plms_ind]).meas_num )
{
/*If Matches*/
/*Compare with desc code in plotmeas*/
for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
/*Compare with desc code in plotmeas.*/
if (desc_code[desc_ind] == (plms_table

->data[plms_ind]).desc_code)
{
/*If matches get the title and store in
temp_title*/
strcpy(
temp_title[desc_ind][meas_ind],
(plms_table->data[plms_ind]).title);
break;
}
}

}
}
}
for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
for (meas_ind = 0; meas_ind < num_meas; meas_ind++)
{
printf("temp_title[%d][%d] = %7s ",desc_ind, meas_ind,
temp_title[desc_ind][meas_ind]);
}
printf("\n");
}

for (desc_ind = 0; desc_ind < num_desc; desc_ind++)
{
free(temp_title[desc_ind]); /*Program crashes here*/
And since malloc is now completely confused, free gets confused to.

Be thankful, a program crash is one of the better manifestations of
undefined behavior.
}
free(temp_title);
}

snip code for main
<<Remove the del for email>>
Dec 2 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Java and Swing | last post by:
static PyObject *wrap_doStuff(PyObject *self, PyObject *args) { // this will store the result in a Python object PyObject *finalResult; // get arguments from Python char *result = 0; char *in=...
20
by: ghyott | last post by:
hello, In my opinion the following code should crash when run with *(argv+1)="1234567890" and *(argv+2)="1234567890" . int main(int argc,char **argv) { char buf1; char buf2; char buf3;...
29
by: keredil | last post by:
Hi, Will the memory allocated by malloc get released when program exits? I guess it will since when the program exits, the OS will free all the memory (global, stack, heap) used by this...
4
by: Atul Sureka | last post by:
Hi, I want to free the object memory in C# - like we do using 'delete' keyword in C++. Lets say I have an object of some class and I want to explicitly free the memory. C# do not have any free...
41
by: SkyBlue | last post by:
Hi, can someone explain why the following simple C code segfaulted? I've stared it for 30mins but couldn't find the problem. Thx in advance #include <stdio.h> int main() { char *one; char...
42
by: Sheldon | last post by:
Hi, This program works when tested with gdb ( see results 1) but when used in a larger program where 12 becomes 1500 there exists a problem when freeing the memory ( see results 2). Can anyone...
14
by: srinivas | last post by:
hi, i am incrementing a list iterator "m_item" in my .cpp file m_item._ptr->_next is showing the valid item. but in the library overloaded function for ++ 1 >_Myt_iter operator++(int) 2...
41
by: z | last post by:
I use Visual C 2005 to develop my programs. One in particular is crashing in very specific and hard to replicate situations, made worse by the fact it only crashes when run -outside- the dev - as...
4
by: mike3 | last post by:
Hi. I seem to have made some progress on finding that bug in my program. I deactivated everything in the bignum package that was used except for the returning of BigFloat objects. I even...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.