Thread: A bug I cannot see. . . malloc issue

  1. #1
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065

    A bug I cannot see. . . malloc issue

    System: WindowsXP
    IDE: Code::Blocks
    Compiler: gcc (GCC) 3.4.4 (mingw special) <- Comes with Code::Blocks

    The code:
    Code:
    LINE_TEXT **settreelist(char *filename)
    /*
    	Given:	A string.
    	Return:	A LINE_TEXT array or NULL on error.
    	Task:	The filename is an adf file format and is the current selected file for the main program.
    		Run through the file and pull out all the potential times.  The format will be
    		HH:MM:SS AAMMMM.  Two examples of this are "00:23:38 GB STL" and "22:14:49 HDIDLH".
    	NOTE:	There will be only one space for any Method name that contains four characters, otherwise,
    		there is a space between the Agent and Method names.  Also, a return of NULL could mean
    		that there is no such file, or that there are no records in the file.
    */
    {
    	int i, k;
    	LINE_TEXT **list;
    	TMRI_PARAMREC p;
    
    //	k = getnumrecs(filename);
    // The file only has one record in it -- weeding out any possible problems in another source file.
    k = 1;
    	k *= 2;
    	if (k <= 0)
    		return NULL;
    	list = (LINE_TEXT **) malloc(sizeof(LINE_TEXT *) * (k + 1));
    	list[k] = NULL;
    debugmessage(mainwnd, "About to loop.");
    	for (i = 0; i < k; i++){
     		list[i] = (LINE_TEXT *) malloc(sizeof(LINE_TEXT));
    		list[i]->text = (char *) malloc(sizeof(char) * 10);
    //		getnrec(filename, &p, i/2);
    // Revmoved during the debug -- attempting to narrow down the problem.
    p.times[TIME_TIME].hour = 12;
    p.times[TIME_TIME].minute = 20;
    p.times[TIME_TIME].second = 33;
    p.floats[FLOAT_CONCENTRATION] = 1.23; // Force the first if.
    p.floats[FLOAT_ALARMSETPOINT] = 0.23;
    strcpy(p.agentname, "AK");
    strcpy(p.methodname,"KJK");
    		sprintf(list[i]->text, "%02i:%02i:%02i", (int) p.times[TIME_TIME].hour, (int) p.times[TIME_TIME].minute, (int) p.times[TIME_TIME].second);
    		if (p.floats[FLOAT_CONCENTRATION] >= p.floats[FLOAT_ALARMSETPOINT]){
    			if(get_packederrors(p.bytes[BYTE_PACKEDBITS])){
    				list[i]->bgcolor = LINE_COLOR_BGTREEALARM_ERROR;
    				list[i]->fgcolor = LINE_COLOR_FGTREEALARM_ERROR;
    			} else {
    				list[i]->bgcolor = LINE_COLOR_BGTREEALARM;
    				list[i]->fgcolor = LINE_COLOR_FGTREEALARM;
    			}
    		} else if (get_packederrors(p.bytes[BYTE_PACKEDBITS])) {
    			list[i]->bgcolor = LINE_COLOR_BGTREEERROR;
    			list[i]->fgcolor = LINE_COLOR_FGTREEERROR;
    		} else {
    			list[i]->bgcolor = LINE_COLOR_BGTREEDEFAULT;
    			list[i]->fgcolor = LINE_COLOR_FGTREEDEFAULT;
    		}
    		i++;
    debugmessage(mainwnd, "About to malloc first.");
    		list[i] = (LINE_TEXT *) malloc(sizeof(LINE_TEXT));
    debugmessage(mainwnd, "Done with first, now second malloc");
    		list[i]->text = (char *) malloc(sizeof(char) * 10);
    debugmessage(mainwnd, "Done with second malloc. -- Never see this one as we crash.");
    		sprintf(list[i]->text, " %s%s%s", p.agentname, (strlen(p.methodname) > 3) ? "" : " ",
    						  p.methodname);
    		list[i]->bgcolor = LINE_COLOR_BGTREEDEFAULT;
    		list[i]->fgcolor = LINE_COLOR_FGTREEDEFAULT;
    	}
    debugmessage(mainwnd, "About to return");
    	return list;
    }
    The location it fails is marked within the debug message, but it is the fourth malloc. This is code that has been working just fine, however, I have had to add in additional support for a new revision of two of the structures -- so it _could_ be somewhere else in the code, however, I have removed _ALL_ references to the new code (as you can see above) and I'm still getting the same thing. I'm a Linux programmer so I don't get how to use Code::Blocks' debugger. . . and it is not like I'm getting a core file (can this be done in WindowsXP?) to examine.

    Any help would be greatly appreciated.

    Andy

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    If you break that out into a test program, does it still crash?
    My best code is written with the delete key.

  3. #3
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    If I break this out into a test program it won't even compile, let alone run. There is way too much that happens before this - which leads in to this question:

    If I segment somewhere well before -- Is windows too stupid to realize this and kicks me out late? Like maybe _AFTER_ I request more memory?

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    What do LINE_TEXT and TMRI_PARAMREC look like? And maybe some of the others like TIME_TIME?

    Does adding NULL checking help any?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Is windows too stupid to realize this and kicks me out late?
    That's possible on any system. The symptom of a memory error can happen long after the cause as long as you don't do anything that forces the process to panic.
    My best code is written with the delete key.

  6. #6
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Quote Originally Posted by Dave_Sinkula View Post
    What do LINE_TEXT and TMRI_PARAMREC look like? And maybe some of the others like TIME_TIME?
    For TMRI_PARAMREC, this is not an easy question to answer, so I posted the reply in code -- It is a very large structure.

    LINE_TEXT is simply:
    Code:
    typedef struct {
    	char *text;
    	int bgcolor, fgcolor;
    } LINE_TEXT;
    Quote Originally Posted by Dave_Sinkula View Post
    Does adding NULL checking help any?
    Nope, it doesn't return NULL. These structures aren't that big.

    Code:
    #ifndef __DATAFILE_H
    #define __DATAFILE_H
    #define VERSION_HEADER_STRING "Data Generated by ADACS Version %s\nDates are listed as JDO\n"
    #define ADACS_VERSION_NUMBER "2.0.2"
    #define VERSION_HEADER_VARS ADACS_VERSION_NUMBER
    
    
    #ifndef DONOTDEFINEBITFUNCS
    #define setbit(b, d)	do {\
    				b |= (1 << (d));\
    			} while (0)
    #define clearbit(b, d)	do {\
    				b &= ~(1 << (d));\
    			} while (0)
    #define testbit(b, d)	(b & (1 << (d)))
    #endif
    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    // Universal Data.
    extern char *ERRORSTRING[];
    extern char *GATESTRING[];
    extern char *FLOWSTRING[];
    extern char *TEMPSTRING[];
    extern char *PRINTFILE[];
    
    //PRINTFILE enum:
    enum TMRI_PRINTFILE_LINES{
    	PFLINE_FIRST = 0,
    	PFLINE_ACAMS_PARAMETERS = PFLINE_FIRST,	// 0
    	PFLINE_AGT_METH_CONC,			// 1
    	PFLINE_NUMAGTS_UNIT,			// 2
    	PFLINE_T_ELAPASED_SPEC,			// 3
    	PFLINE_TMP_AMB,				// 4
    	PFLINE_TMP_FLAME,			// 5
    	PFLINE_TMP_BLOCK,			// 6
    	PFLINE_TMP_VALVE,			// 7
    	PFLINE_TMP_PCT,				// 8
    	PFLINE_TMP_PCT_LO,			// 9
    	PFLINE_TMP_PCT_HI,			// 10
    	PFLINE_TMP_COL,				// 11
    	PFLINE_TMP_COL1_LO,			// 12
    	PFLINE_TMP_COL1_STEP,			// 13
    	PFLINE_TMP_COL1_HI,			// 14
    	PFLINE_TMP_COL2_LO,			// 15
    	PFLINE_TMP_COL2_STEP,			// 16
    	PFLINE_TMP_COL2_HI,			// 17
    	PFLINE_FLOW_N2,				// 18
    	PFLINE_FLOW_H2,				// 19
    	PFLINE_FLOW_AIR,			// 20
    	PFLINE_FLOW_SAM,			// 21
    	PFLINE_FLOW_SAM_AVG,			// 22
    	PFLINE_TIME_CYCLE,			// 23
    	PFLINE_TIME_PURGE,			// 24
    	PFLINE_TIME_SAMPLE,			// 25
    	PFLINE_TIME_DESORB,			// 26
    	PFLINE_TIME_COL1,			// 27
    	PFLINE_TIME_COL2,			// 28
    	PFLINE_TIME_ZERO,			// 29
    	PFLINE_TIME_AGENT,			// 30
    	PFLINE_TIME_INJECT,			// 31
    	PFLINE_VOLT_PMT,			// 32
    	PFLINE_ELEC_PMTSIG,			// 33
    	PFLINE_ELEC_BUCK_COARSE,		// 34
    	PFLINE_ELEC_BUCK_FINE,			// 35
    	PFLINE_PK_HT,				// 36
    	PFLINE_PK_RT,				// 37
    	PFLINE_PK_FWHM,				// 38
    	PFLINE_PK_BL,				// 39
    	PFLINE_CAL_HT,				// 40
    	PFLINE_CAL_NUM,				// 41
    	PFLINE_CAL_TIMESTAMP,			// 42
    	PFLINE_CAL_ALARM,			// 43
    	PFLINE_SPLIT_CNTRL_STAT,		// 44
    	PFLINE_SPLIT_GATE,			// 45
    	PFLINE_SPLIT_DELTAFLOW,			// 46
    	PFLINE_SPLIT_FLOW_MAIN,			// 47
    	PFLINE_SPLIT_FLOW_VENT,			// 48
    	PFLINE_SPLIT_PRES_MAIN,			// 49
    	PFLINE_SPLIT_PRES_VENT,			// 50
    	PFLINE_SPLIT_FIRST = PFLINE_SPLIT_CNTRL_STAT,
    	PFLINE_SPLIT_LAST = PFLINE_SPLIT_PRES_VENT,
    	PFLINE_NL_SEPARATOR,			// 51
    	PFLINE_LAST = PFLINE_NL_SEPARATOR
    };
    
    // Universal enums
    enum TMRI_BYTES {
    	BYTE_FIRST = 0,
    	BYTE_NUMAGENTS = BYTE_FIRST,
    	BYTE_WHICHAGENT,
    	BYTE_PACKEDBITS,
    	BYTE_LAST = BYTE_PACKEDBITS
    };
    
    #define PACKED_ALARM		0x01 // only one bit
    #define PACKED_ERRORS		0x02 // only one bit
    #define PACKED_NUMCALS		0x1c // three bits
    #define PACKED_COMPLETECHROM	0x20 // only one bit
    
    enum TMRI_STATE_FLAGS{
    	SFLAG_FIRST = 0,
    	SFLAG_CALMODE = SFLAG_FIRST,
    	SFLAG_CHALLENGE,
    	SFLAG_REPAIR,
    	SFLAG_SERVICE,
    	SFLAG_ADJUSTMODE,
    	SFLAG_NORMAL,
    	SFLAG_LAST = SFLAG_NORMAL
    };
    #define NUM_STATE_FLAGS		(SFLAG_LAST - SFLAG_FIRST + 1)
    #define NUM_STATE_FLAGS_BYTES	(NUM_STATE_FLAGS / 8 + ((NUM_STATE_FLAGS % 8) ? 1:0))
    
    #define setstateflags(flags, which)	setbit(flags[which / 8], which % 8)
    #define clearstateflags(flags, which)	clearbit(flags[which / 8], which % 8)
    #define teststateflags(flags, which)	testbit(flags[which / 8], which % 8)
    
    enum TMRI_CHROM_SHORTS {
    	CHROM_SHORTS_FIRST = 0,
    	CHROM_SHORTS_CHROMLEN = CHROM_SHORTS_FIRST,
    	CHROM_SHORTS_RC0S,			// Real start of Agent gate for Agent 0
    	CHROM_SHORTS_RC0E,			// Real end of Agent gate for Agent 0
    	CHROM_SHORTS_RC1S,			// Real start of Agent gate for Agent 1
    	CHROM_SHORTS_RC1E,			// Real end of Agent gate for Agent 1
    	CHROM_SHORTS_LAST = CHROM_SHORTS_RC1E
    };
    
    enum TMRI_DATES{
    	DATE_FIRST = 0,
    	DATE_DATE = DATE_FIRST,
    	DATE_CALDATE,
    	DATE_LAST = DATE_CALDATE
    };
    
    enum TMRI_ERRORS {
    	ERROR_FIRST = 0,
    	ERROR_RPCT = ERROR_FIRST,
    	ERROR_RCOL,
    	ERROR_TFFL,
    	ERROR_TPCT,			// Placeholder, never used.
    	ERROR_TAMB,
    	ERROR_TFBL,
    	ERROR_TVAL,
    	ERROR_TCOL,			// Placeholder, never used.
    	ERROR_TPLO,
    	ERROR_TPHI,
    	ERROR_TC1L,
    	ERROR_TC1H,
    	ERROR_TC1R,			// Placeholder, never used.
    	ERROR_TC2L,
    	ERROR_TC2H,
    	ERROR_TC2R,			// Placeholder, never used.
    	ERROR_FHYD,
    	ERROR_FNIT,
    	ERROR_FAIR,
    	ERROR_FSAM,
    	ERROR_VPMT,
    	ERROR_PNIT,
    	ERROR_PHYD,
    	ERROR_PAIR,
    	ERROR_SCNT,			// Placeholder, never used.
    	ERROR_STIM,			// Placeholder, never used.
    	ERROR_SDFL,			// Placeholder, never used.
    	ERROR_SSFL,
    	ERROR_SVFL,
    	ERROR_SSPR,
    	ERROR_SVPR,
    	ERROR_SCBL,
    	ERROR_SPWR,
    	ERROR_UMAN,
    	ERROR_LAST = ERROR_UMAN
    };
    
    enum TMRI_FLOATS {
    	FLOAT_FIRST = 0,
    	FLOAT_CONCENTRATION = FLOAT_FIRST,
    	FLOAT_COLUMN1STEP,
    	FLOAT_COLUMN2STEP,
    	FLOAT_PMTSIG,
    	FLOAT_COARSEZERO,
    	FLOAT_FINEZERO,
    	FLOAT_PKHEIGHT,
    	FLOAT_PKHT = FLOAT_PKHEIGHT,
    	FLOAT_RETTIME,
    	FLOAT_FWHM,
    	FLOAT_BASELINE,
    	FLOAT_CALHT,
    	FLOAT_ALARMSETPOINT,
    	FLOAT_LAST = FLOAT_ALARMSETPOINT
    };
    
    enum TMRI_FLOWS {
    	FLOW_FIRST = 0,
    	FLOW_NITROGEN = FLOW_FIRST,
    	FLOW_N2 = FLOW_NITROGEN,
    	FLOW_NIT = FLOW_NITROGEN,
    	FLOW_HYDROGEN,
    	FLOW_H2 = FLOW_HYDROGEN,
    	FLOW_HYD = FLOW_HYDROGEN,
    	FLOW_AIR,
    	FLOW_SAMPLE,
    	FLOW_SAM = FLOW_SAMPLE,
    	FLOW_LAST = FLOW_SAMPLE
    };
    
    enum TMRI_GATES {
    	GATE_FIRST = 0,
    	GATE_CYCLE = GATE_FIRST,
    	GATE_TOTAL = GATE_CYCLE,
    	GATE_PURGE,
    	GATE_SAMPLE,
    	GATE_SAM = GATE_SAMPLE,
    	GATE_DESORB,
    	GATE_COLUMN1,
    	GATE_COL1 = GATE_COLUMN1,
    	GATE_COLUMN2,
    	GATE_COL2 = GATE_COLUMN2,
    	GATE_ZERO,
    	GATE_AGENT,
    	GATE_INJECT,
    	GATE_LAST = GATE_INJECT
    };
    
    enum TMRI_HEADER{
    	HEADER_FIRST = 0,
    	HEADER_NAME = HEADER_FIRST,
    	HEADER_VERSION = 4,
    	HEADER_CODE = 6,
    	HEADER_TYPE = HEADER_CODE,
    	HEADER_LAST
    };
    
    enum TMRI_SHORTS{
    	SHORT_FIRST = 0,
    	SHORT_UNITID = SHORT_FIRST,
    	SHORT_ELAPSEDTIME,
    	SHORT_SAMPLEAVERAGE,
    	SHORT_POINTSLEN,
    	SHORT_LAST = SHORT_POINTSLEN
    };
    
    enum TMRI_TEMPERATURES {
    	TMP_FIRST = 0,
    	TMP_AMBIENT = TMP_FIRST,
    	TMP_AMB = TMP_AMBIENT,
    	TMP_FPD_FLAME,
    	TMP_FLAME = TMP_FPD_FLAME,
    	TMP_FPD_BLOCK,
    	TMP_BLOCK = TMP_FPD_BLOCK,
    	TMP_VALVE,
    	TMP_PCT,
    	TMP_PCT_LOW,
    	TMP_PCT_HIGH,
    	TMP_COLUMN,
    	TMP_COL = TMP_COLUMN,
    	TMP_COLUMN1_LOW,
    	TMP_COL1_LOW = TMP_COLUMN1_LOW,
    	TMP_COLUMN1_HIGH,
    	TMP_COL1_HIGH = TMP_COLUMN1_HIGH,
    	TMP_COLUMN2_LOW,
    	TMP_COL2_LOW = TMP_COLUMN2_LOW,
    	TMP_COLUMN2_HIGH,
    	TMP_COL2_HIGH = TMP_COLUMN2_HIGH,
    	TMP_LAST = TMP_COLUMN2_HIGH
    };
    
    enum TMRI_TIMES{
    	TIME_FIRST = 0,
    	TIME_TIME = TIME_FIRST,
    	TIME_CALTIME,
    	TIME_LAST = TIME_CALTIME
    };
    
    enum TMRI_TYPES{
    	TYPE_FIRST = 0,
    	TYPE_PARAMREC = TYPE_FIRST,
    	TYPE_CHROM,
    	TYPE_CHROMREC = TYPE_CHROM,
    	TYPE_ERRORS,
    	TYPE_ERRORREC = TYPE_ERRORS,
    	TYPE_LAST = TYPE_ERRORS
    };
    
    // Universal Definitions (these don't need to be Universal, but oh well)
    #define FILETYPE_LEN (HEADER_LAST - HEADER_FIRST + 1)
    #define BYTES_LEN (BYTE_LAST - BYTE_FIRST + 1)
    #define CHROM_LEN 249
    #define EXTRABITS_LEN (CHROM_LEN / 8 + ((CHROM_LEN % 8) ? 1:0))
    #define SHORTS_LEN (SHORT_LAST - SHORT_FIRST + 1)
    #define FLOATS_LEN (FLOAT_LAST - FLOAT_FIRST + 1)
    #define DATES_LEN (DATE_LAST - DATE_FIRST + 1)
    #define TIMES_LEN (TIME_LAST - TIME_FIRST + 1)
    #define TEMPERATURES_LEN (TMP_LAST - TMP_FIRST + 1)
    #define TMP_LEN TEMPERATURES_LEN
    #define FLOWS_LEN (FLOW_LAST - FLOW_FIRST + 1)
    #define GATES_LEN (GATE_LAST - GATE_FIRST + 1)
    #define CHROM_SHORTS_LEN (CHROM_SHORTS_LAST - CHROM_SHORTS_FIRST + 1)
    #define CUR_FILECODE 0
    // Universal Data structures.
    #ifndef DONOTDEFINEPACK
    #define __PACK1 __attribute__((aligned (1),packed))
    #endif
    
    struct TMRI_Date{
    	short year;
    	char month, day;
    } __PACK1;
    typedef struct TMRI_Date TMRI_DATE;
    
    struct TMRI_Time{
    	char hour, minute, second;
    } __PACK1;
    typedef struct TMRI_Time TMRI_TIME;
    
    struct TMRI_ShrtSAT{
    	short setpoint, actual, tolerance;
    } __PACK1;
    typedef struct TMRI_ShrtSAT TMRI_SHRTSAT;
    
    struct TMRI_ShrtSE{
    	short start, end;
    } __PACK1;
    typedef struct TMRI_ShrtSE TMRI_SHRTSE;
    
    //Rev 1 addition of Splitter data.
    enum SPLIT_FLOATS{
    	SPLT_F_FIRST = 0,
    	SPLT_F_PRESS_SETPT_MAIN = SPLT_F_FIRST,
    	SPLT_F_PRESS_SETPT_VENT,
    	SPLT_F_PRESS_ACT_MAIN,
    	SPLT_F_PRESS_ACT_VENT,
    	SPLT_F_PRESS_ERROR_MIN_MAIN,
    	SPLT_F_PRESS_ERROR_MIN_VENT,
    	SPLT_F_PRESS_ERROR_MAX_MAIN,
    	SPLT_F_PRESS_ERROR_MAX_VENT,
    	SPLT_F_FLOW_SETPT_MAIN,
    	SPLT_F_FLOW_SETPT_VENT,
    	SPLT_F_FLOW_ACT_MAIN,
    	SPLT_F_FLOW_ACT_VENT,
    	SPLT_F_FLOW_DELTA,
    	SPLT_F_LAST = SPLT_F_FLOW_DELTA
    };
    #define SPLT_FLOATS_LEN	(SPLT_F_LAST - SPLT_F_FIRST + 1)
    enum SPLIT_FLAGS{
    	FSPLT_FIRST = 0,
    	FSPLT_EXISTS = FSPLT_FIRST,
    	FSPLT_ON,
    	FSPLT_LAST = FSPLT_ON
    };
    #define SPLT_FLAGS_LEN (FSPLT_LAST - FSPLT_FIRST + 1)
    #define SPLT_FLAGS_BYTES (SPLT_FLAGS_LEN / 8 + ((SPLT_FLAGS_LEN % 8) ? 1:0))
    struct TMRI_Splt{
    	float floats[SPLT_FLOATS_LEN];
    	char flags[SPLT_FLAGS_BYTES];
    	short flowtol[2]; // Vent and main flow tol.
    	TMRI_SHRTSE times;
    } __PACK1;
    typedef struct TMRI_Splt TMRI_SPLT;
    
    struct TMRI_ParamRec_R1{
    	char filetype[FILETYPE_LEN];
    	float floats[FLOATS_LEN];
    	short shorts[SHORTS_LEN], chrom[CHROM_LEN];
    	TMRI_DATE dates[DATES_LEN];
    	TMRI_TIME times[TIMES_LEN];
    	TMRI_SHRTSAT temperatures[TMP_LEN];
    	TMRI_SHRTSAT flows[FLOWS_LEN];
    	TMRI_SHRTSAT pmtvoltage;
    	TMRI_SHRTSE gates[GATES_LEN];
    	char agentname[3], methodname[5], bytes[BYTES_LEN], extrabits[EXTRABITS_LEN];
    	int startofcycle;						// Rev 1.  Secs since EPOC, time cycle started.
    	TMRI_SPLT split;						// Rev 1.  Splitter information.
    	unsigned char flags[NUM_STATE_FLAGS_BYTES];			// Rev 1.  Numerous flags giving the ACAMS state.
    } __PACK1;
    typedef struct TMRI_ParamRec_R1 TMRI_PARAMREC_R1;
    
    struct TMRI_ParamRec_R0{
    	char filetype[FILETYPE_LEN];
    	float floats[FLOATS_LEN];
    	short shorts[SHORTS_LEN], chrom[CHROM_LEN];
    	TMRI_DATE dates[DATES_LEN];
    	TMRI_TIME times[TIMES_LEN];
    	TMRI_SHRTSAT temperatures[TMP_LEN];
    	TMRI_SHRTSAT flows[FLOWS_LEN];
    	TMRI_SHRTSAT pmtvoltage;
    	TMRI_SHRTSE gates[GATES_LEN];
    	char agentname[3], methodname[5], bytes[BYTES_LEN], extrabits[EXTRABITS_LEN];
    } __PACK1;
    typedef struct TMRI_ParamRec_R0 TMRI_PARAMREC_R0;
    
    #define TMRI_PARAMREC_VERSION 1
    
    struct TMRI_ChromRec_R0 {
    	char filetype[FILETYPE_LEN]; // adf + file code.
    	short shorts[CHROM_SHORTS_LEN], *chrom;
    	char *extrabits;
    } __PACK1;
    typedef struct TMRI_ChromRec_R0 TMRI_CHROMREC_R0;
    
    #define TMRI_CHROMREC_VERSION 0
    
    struct TMRI_ErrorDetail_R0{
    	char code[1];	// (ERRORS & 0xff)
    	short time;	// Cycle Time
    } __PACK1;
    typedef struct TMRI_ErrorDetail_R0 TMRI_ERRORDETAIL_R0;
    
    struct TMRI_ErrorDetail_R1{
    	char code;	// (ERRORS & 0xff)  			// Rev 1, removed the array changed to just byte.
    	TMRI_TIME time;	// Cycle Time				// Rev 1, changed to a TMRI_TIME.
    } __PACK1;
    typedef struct TMRI_ErrorDetail_R1 TMRI_ERRORDETAIL_R1;
    
    typedef TMRI_ERRORDETAIL_R1 TMRI_ERRORDETAIL;
    
    struct TMRI_Errors_R0 {
    	char filetype[FILETYPE_LEN];
    	short len;
    	TMRI_ERRORDETAIL_R0 *list;
    } __PACK1;
    typedef struct TMRI_Errors_R0 TMRI_ERRORS_R0, TMRI_ERRORREC_R0;
    
    struct TMRI_Errors_R1 {
    	char filetype[FILETYPE_LEN];
    	short len;
    	TMRI_ERRORDETAIL_R1 *list;
    } __PACK1;
    typedef struct TMRI_Errors_R1 TMRI_ERRORS_R1, TMRI_ERRORREC_R1;
    #define TMRI_ERRORREC_VERSION 1
    
    // Universal struct Type defs (to set the current REC needed).
    #define LARGEST_PARAMREC_SIZE (sizeof(TMRI_PARAMREC_R0))
    typedef TMRI_PARAMREC_R1 TMRI_PARAMREC;
    typedef TMRI_CHROMREC_R0 TMRI_CHROMREC;
    typedef TMRI_ERRORREC_R1 TMRI_ERRORS, TMRI_ERRORREC;

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > sprintf(list[i]->text, " %s%s%s", p.agentname, (strlen(p.methodname) > 3) ? "" : " ",
    > p.methodname);
    You expect this to be always < 10 characters?

    If you're using Linux, then I would suggest
    gcc -g prog.c -lefence
    and run the resulting executable in the debugger.

    If electric fence is doing it's job properly, it should trap into the debugger on the very instruction which accesses outside of allocated memory space. This is usually a much better idea than rummaging through some random segfault later on which has nothing to do with the root cause problem.
    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.

  8. #8
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Quote Originally Posted by Salem View Post
    > sprintf(list[i]->text, " %s%s%s", p.agentname, (strlen(p.methodname) > 3) ? "" : " ",
    > p.methodname);
    You expect this to be always < 10 characters?

    If you're using Linux, then I would suggest
    gcc -g prog.c -lefence
    and run the resulting executable in the debugger.

    If electric fence is doing it's job properly, it should trap into the debugger on the very instruction which accesses outside of allocated memory space. This is usually a much better idea than rummaging through some random segfault later on which has nothing to do with the root cause problem.
    Does electric fence work in WindowsXP? I'm not in Linux right now -- else I would have already found the problem. . . I'm like a fish outta water in Windows.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    sprintf with "%02i:%02i:%02i" will give you 8 chars if the numbers are in 2-digit range, but a negative number or one that is 100 will add extra chars. Two of those will overwrite the end of the string, which is highly likely to get you into trouble. Check that the string is not above 9 chars long (because you allocated 10).

    You could of course allocate extra space in the first place, e.g. allocate 100 bytes, and see what happens.

    Or store the string in a local buffer that is always guaranteed to be big enough, and then malloc the right amount and copy it from the buffer. It's fairly easy with numbers, since no 32-bit integer can be more than about 11 digits, so a 3-numbers + some extra bits would be about 40 chars long - say 48 to make it a nice multiple of a 2^n number (3 * 16 = 3 * 2^4).

    You can also check how many characters sprintf() gave by looking at the return value. If sprintf returns a number more than 9, your current malloc is too small. [or, put another way, your data don't fit in the buffer - it could of course be that the BUFFER is the right size, but the data is bad - impossible for me to say which is the "right" answer here]

    The second thing you could do is to print the actual pointer value (printf("%p\n", someptr)), and check that it's a sensible value (e.g. it looks similar to other pointers recently allocated. Do this for all your pointers - if you get 0x4001210, 0x4001250, 0xF377E190, then the latter value is suspect [These are simply made up numbers, but you should be able to see a pattern between each allocation, and if it looks completely different it's suspect to say the least]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Does electric fence work in WindowsXP?
    Sorry, I mis-read your post then, I just saw the Linux bit and didn't tweak you were actually on windows.
    And you actually said so at the start Mea culpa
    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.

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by Kennedy View Post
    I'm a Linux programmer so I don't get how to use Code::Blocks' debugger
    Build the debug build and use stuff in the Debug menu, I guess -- seems relatively straightforward to me.

    As a standalone, I observed no crash from this code.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  12. #12
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    It appears that this code is just a symptom of another code block earlier in the process. Somewhere around where I'm bringing in my data. So, it is as Prelude led me to believe, Windows isn't catching my stomping memory until much later (like 6 lines in the main program ~= 200 lines of code).

    Thanks for yall's help!

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, it's fairly common to NOT get slapped on the fingers with memory problems until much later - this is not specific in Windows, it applies just as well to Linux, OS/2 and any other OS. Only when there are built-in safe-guards in the memory allocation routines themselves can you detect these things. A big portion of the problem is that the memory you are overwriting when writing beyond the end of a malloc'ed area of memory is completely undefined - it may be some other data, it may not be used, it may be invalid if you are lucky. One of the worst ones is when it's not used for anything - but running with a different set of data makes it used. You can bet that this will only be discovered when a CUSTOMER uses the code.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >The location it fails is marked within the debug message, but it is the fourth malloc.
    That actually makes sense, since you increment i twice each time through the loop, so you go past the end of the array.

  15. #15
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Quote Originally Posted by swoopy View Post
    >The location it fails is marked within the debug message, but it is the fourth malloc.
    That actually makes sense, since you increment i twice each time through the loop, so you go past the end of the array.
    Note that k *= 2 after it reads in how big the store is. The reason is that this particular array is the text for a list box that has the format:
    HH:MM:SS AAMMMM
    and is configured for having the time and Agent+Method in different colors. Therefore, I had to put the two strings into different locations so that I'd know the FG&BG colors.

    So, no, that isn't the problem. This _was_ working code. It appears that it has to do with the version control. I don't think that I'm storing my structure correctly into the store when I do my read. Probably has something to do with the fwrite() in another file. That's what I'm guessing as it doesn't work for import on either Rev 0 or Rev 1 of the data.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. malloc + segmentation fault
    By ch4 in forum C Programming
    Replies: 5
    Last Post: 04-07-2009, 03:46 PM
  2. Is there a limit on the number of malloc calls ?
    By krissy in forum Windows Programming
    Replies: 3
    Last Post: 03-19-2006, 12:26 PM
  3. Malloc and calloc problem!!
    By xxhimanshu in forum C Programming
    Replies: 19
    Last Post: 08-10-2005, 05:37 AM
  4. malloc() & address allocation
    By santechz in forum C Programming
    Replies: 6
    Last Post: 03-21-2005, 09:08 AM
  5. malloc always setting length of 8?
    By Zarkhalar in forum C++ Programming
    Replies: 7
    Last Post: 08-01-2004, 11:36 PM