Advertisement

Some basic questions...

Started by May 29, 2001 08:35 AM
7 comments, last by the_grip 23 years, 8 months ago
Couple probelms i''m having... 1. (C++) When i have an array of structures as a globabl variable, can i use realloc() to change the actual size of the array (given that i know the new size desired)? 2. (C/C++) When i output file text in binary format to a file, char string[x] (where x is whatever the length of the array is) writes fine, but any variables declared char* string do not. Obviously, char* is a pointer, but does anyone know a way to output a char* variable to a binary file? (i''m using the C notation for file i/o - i.e. fopen, fread, fwrite, fclose, etc.) Thanks!!! "You call him Dr. Grip, doll!"
"You call him Dr. Grip, doll!"
1. Yes, you can call realloc with the already malloc''d structure and the new size.

2. If you want to write TO the string, you need to malloc it first. To write the string into a file, use fprintf(file, string, ...)

Darkening
Advertisement
Cool, so in regards to #1, i can actually increase the size of the global array - i.e. if there are five structures in it, i can expand it or reduce it to hold the desired amount?

"You call him Dr. Grip, doll!"
"You call him Dr. Grip, doll!"
I''m not sure about your first question. I think if you declare your global array of structures as a pointer, you can allocate and reallocate memory for it. But I doubt if you can reallocate the memory of an array allocated on the stack (hard-coded initial size). Be sure that when you allocate and re-allocate memory for the array, you multiply the parameter by the size of the structure:

struct stMyStruct *arst = (struct stMyStruct *)malloc(nElements * sizeof(struct stMyStruct))

And to answer your second question, not everything is done for you in C . The IO functions *will* write consecutive bytes from memory to a file for you, but they''re not going to identify, dereference and byte-count pointers for you while writing to a file. If you have a fixed-size structure (for instance, if all your strings have a hard coded size) then all the data is contiguous in memory and it''s easy to write. But if you want your data to vary in size you will have to write out the elements of your structure individually, prefix each string (or variable-length element) with a length and then write out the value of the string in a separate step. The string is stored in a different memory location from the rest of the structure, which can''t be reliably predicted (as far as I know). Then when reading the structure you will have to read the length prefix, allocate a buffer of that length, then read that many bytes from the file into the new buffer. Be sure to keep track of the separate lengths if you''re using null-terminated strings: the string (excluding the null-terminator) has one fewer character than the buffer. Assign the pointer to that new buffer to the structure member corresponding to the string. At some level or another, this is how it has to be done internally anyway.

"All you need to do to learn circular logic is learn circular logic"

"All you need to do to learn circular logic is learn circular logic"
You should only use realloc on pointers whose data have been allocated with malloc or calloc!

Calling realloc on a global array declared as for example:

int foo[100];

will not work and will probably cause a Segmentation Fault or something similar.

Calling realloc on data allocated by new or new[] will not work either.
Could someone write an example of number two out - both for reading and writing? Thanks!!

"You call him Dr. Grip, doll!"
"You call him Dr. Grip, doll!"
Advertisement
Maybe this is a better idea... here is my code, but it doesn''t seem to work. i''ll post the writing code in one post, then the reading in another:

#include #include #include #include #include #include struct m_stMapFileHeader{		char* m_cMapTitleName;	int iLengthOfMapTitleName;	unsigned int m_iMapWidth, m_iMapHeight, m_iNumTileStructs, m_iNumNPCStructs;} *m_stMapHeader;struct m_stTileHeader{	char* m_scTileFileName;	int iLengthOfFileName;	char* m_scTileTitleName;	int iLengthOFTileTitleName;	char m_scFileType[3]; //bitmap, gif, etc.} *m_stTileSetHeader;struct m_stTileBody{	unsigned int m_iTileID;  //give each tile used in the map a unique id for reference in drawing	unsigned int m_siNumberOfAnimations;  //indicate the animations of a tile graphic (i.e. flashing lights, water, etc.)	unsigned int m_siAnimationTileIDList[100];  //graphic ID names for tiles - don''t need to really be in any order	unsigned int m_siNumberOfIndoorTiles; //indicate how many tiles will lie underneath the surface tile (i.e. floors of a building, etc.)	unsigned int m_siIndoorTileIDList[100]; //graphic file names for tiles - make first one the default (i.e. the roof of a building)	bool m_sbWalkable, m_sbFlyable, m_sbSwimOrWadeable, m_sbBoatable, m_sbTransdimensional, m_sbBlocksVision;} *m_stTileSetBody; FILE *fp;int a;void main(void){	a=0;	char* cMapFileTitle = "TestMap.map";		m_stMapHeader=(struct m_stMapFileHeader*)malloc(sizeof(m_stMapFileHeader));	m_stTileSetHeader=(struct m_stTileHeader*)malloc(2*sizeof(m_stTileHeader));	m_stTileSetBody=(struct m_stTileBody*)malloc(2*sizeof(m_stTileBody));	m_stMapHeader[0].m_cMapTitleName="TestMap";	m_stMapHeader[0].iLengthOfMapTitleName=strlen(m_stMapHeader[0].m_cMapTitleName);	m_stMapHeader[0].m_iMapWidth=800;	m_stMapHeader[0].m_iMapHeight=600;	m_stMapHeader[0].m_iNumTileStructs=2;	m_stMapHeader[0].m_iNumNPCStructs=0;	for(unsigned int x;x<=100;x++)	{		m_stTileSetBody[0].m_siAnimationTileIDList[x]=0;		m_stTileSetBody[0].m_siIndoorTileIDList[x]=0;		m_stTileSetBody[1].m_siAnimationTileIDList[x]=0;		m_stTileSetBody[1].m_siIndoorTileIDList[x]=0;	}	m_stTileSetHeader[0].m_scTileFileName="tilepic1.bmp";	m_stTileSetHeader[0].iLengthOfFileName=strlen(m_stTileSetHeader[0].m_scTileFileName);	m_stTileSetHeader[0].m_scTileTitleName="temp1";	m_stTileSetHeader[0].iLengthOFTileTitleName=strlen(m_stTileSetHeader[0].m_scTileTitleName);	strcpy(m_stTileSetHeader[0].m_scFileType, "bmp");	m_stTileSetBody[0].m_iTileID=0;	m_stTileSetBody[0].m_siNumberOfAnimations=0;	m_stTileSetBody[0].m_siNumberOfIndoorTiles=0;	m_stTileSetBody[0].m_sbWalkable=true;	m_stTileSetBody[0].m_sbFlyable=true;	m_stTileSetBody[0].m_sbSwimOrWadeable=true;	m_stTileSetBody[0].m_sbBoatable=false;	m_stTileSetBody[0].m_sbTransdimensional=true;	m_stTileSetBody[0].m_sbBlocksVision=false;	m_stTileSetHeader[1].m_scTileFileName="tilepic2.bmp";	m_stTileSetHeader[1].iLengthOfFileName=strlen(m_stTileSetHeader[1].m_scTileFileName);	m_stTileSetHeader[1].m_scTileTitleName="temp2";	m_stTileSetHeader[1].iLengthOFTileTitleName=strlen(m_stTileSetHeader[1].m_scTileTitleName);	strcpy(m_stTileSetHeader[1].m_scFileType, "bmp");	m_stTileSetBody[1].m_iTileID=0;	m_stTileSetBody[1].m_siNumberOfAnimations=0;	m_stTileSetBody[1].m_siNumberOfIndoorTiles=0;	m_stTileSetBody[1].m_sbWalkable=true;	m_stTileSetBody[1].m_sbFlyable=true;	m_stTileSetBody[1].m_sbSwimOrWadeable=true;	m_stTileSetBody[1].m_sbBoatable=false;	m_stTileSetBody[1].m_sbTransdimensional=true;	m_stTileSetBody[1].m_sbBlocksVision=false;	fp=fopen("TestMap.map", "wb+");	fwrite(&m_stMapHeader[0].iLengthOfMapTitleName, sizeof(m_stMapHeader[0].iLengthOfMapTitleName), 1, fp);	fwrite(&m_stMapHeader[0].m_cMapTitleName, strlen(m_stMapHeader[0].m_cMapTitleName), 1,fp);	fwrite(&m_stMapHeader[0].m_iMapWidth, sizeof(m_stMapHeader[0].m_iMapWidth), 1, fp);	fwrite(&m_stMapHeader[0].m_iMapHeight, sizeof(m_stMapHeader[0].m_iMapHeight), 1, fp);	fwrite(&m_stMapHeader[0].m_iNumTileStructs, sizeof(m_stMapHeader[0].m_iNumTileStructs), 1, fp);	fwrite(&m_stMapHeader[0].m_iNumNPCStructs, sizeof(m_stMapHeader[0].m_iNumTileStructs), 1, fp);	for(int j=0; j<2; j++)	{		fwrite(&m_stTileSetHeader[j].iLengthOfFileName, sizeof(m_stTileSetHeader[j].iLengthOfFileName), 1, fp);		fwrite(&m_stTileSetHeader[j].m_scTileFileName, strlen(m_stTileSetHeader[j].m_scTileFileName), 1, fp);		fwrite(&m_stTileSetHeader[j].iLengthOFTileTitleName, sizeof(m_stTileSetHeader[j].iLengthOFTileTitleName), 1, fp);		fwrite(&m_stTileSetHeader[j].m_scTileTitleName, strlen(m_stTileSetHeader[j].m_scTileTitleName), 1, fp);		fwrite(&m_stTileSetHeader[j].m_scFileType, sizeof(m_stTileSetHeader[j].m_scFileType), 1, fp);		fwrite(&m_stTileSetBody[j], sizeof(m_stTileSetBody), 1, fp);	}			for(unsigned int z=0;z<((m_stMapHeader[0].m_iMapHeight/32)*(m_stMapHeader[0].m_iMapWidth/32));z++)	{		if(a==0){a=1;}		else{a=0;}		fwrite(&a, sizeof(int), 1, fp);			}fclose(fp);free(m_stTileSetBody);free(m_stTileSetHeader);free(m_stMapHeader);} 
---Do i need these above frees? i get the return code of 1 when i do (i''m just trying this stuff out from the console before i implement it) i know i have too many include files as well...



"You call him Dr. Grip, doll!"
"You call him Dr. Grip, doll!"
Now, the reading code (assuming the same structures):
void main(void){	fp=fopen("TestMap.map", "rb");		fread(&m_stMapHeader[0].iLengthOfMapTitleName, sizeof(m_stMapHeader[0].iLengthOfMapTitleName), 1, fp);	char *temp = (char*)malloc(sizeof(m_stMapHeader[0].iLengthOfMapTitleName+1));	fread(temp, sizeof(m_stMapHeader[0].iLengthOfMapTitleName), 1, fp);	strcat(temp, "\n");	m_stMapHeader[0].m_cMapTitleName=temp;		//read in the map header	fread(&m_stMapHeader[0].m_iMapWidth, sizeof(m_stMapHeader[0].m_iMapWidth), 1, fp);	fread(&m_stMapHeader[0].m_iMapHeight, sizeof(m_stMapHeader[0].m_iMapHeight), 1, fp);	fread(&m_stMapHeader[0].m_iNumTileStructs, sizeof(m_stMapHeader[0].m_iNumTileStructs), 1, fp);	fread(&m_stMapHeader[0].m_iNumNPCStructs, sizeof(m_stMapHeader[0].m_iNumNPCStructs), 1, fp);	//now read in the four related structs (2 tileheaders, 2 tilebodies)	for(int j=0;j<2;j++)	{		fread(&m_stTileSetHeader[j].iLengthOfFileName, sizeof(m_stTileSetHeader[j].iLengthOfFileName), 1, fp);		temp =(char*)realloc(temp, sizeof(m_stTileSetHeader[j].iLengthOfFileName+1));		strcat(temp, "\n");		m_stTileSetHeader[j].m_scTileFileName=temp;				fread(&m_stTileSetHeader[j].iLengthOFTileTitleName, sizeof(m_stTileSetHeader[j].iLengthOFTileTitleName), 1, fp);		temp = (char*)realloc(temp, sizeof(m_stTileSetHeader[j].iLengthOFTileTitleName+1));		strcat(temp, "\n");		m_stTileSetHeader[j].m_scTileTitleName=temp;		fread(&m_stTileSetHeader[j].m_scFileType, sizeof(m_stTileSetHeader[j].m_scFileType), 1, fp);		fread(&m_stTileSetBody[j], sizeof(m_stTileSetBody), 1, fp);	}	free(temp);		fread(m_stTileSetBody, sizeof(m_stTileSetBody), 1, fp);	unsigned int z[468];	for(unsigned int x=0;x<468;x++)	{		fread(&z[x], sizeof(int), 1, fp);	}	fclose(fp);	free(temp);} 


"You call him Dr. Grip, doll!"
"You call him Dr. Grip, doll!"
use the "source" tag instead of the "code" tag, it''s a lot easier to read. See?
  #include <math.h>  

#include  

This topic is closed to new replies.

Advertisement