I'm new in C programming and would love to get some help.
I have this struct :
typedef struct house
{
int numOfRooms;
char* houseName;
}HOUSE,*pHOUSE;
I want to create a function that gets a pointer to HOUSE and returns a new pointer to same HOUSE that is located in a different place in memory - the purpose is to be able to change one pointer without changing both :
I will try to be clearer :
pHOUSE duplicate_house(pHOUSE house)
{
pHOUSE newh = (pHOUSE)calloc(1,sizeof(HOUSE));
newh = house
//I get here a pointer that points on the same house.. so If I change for exmample:
// newh->numOfRooms = 9 - > both will change and I don't want it to happen!
}
I read that we can use : memcpy_s
but here If I only had integers inside the struct it could be easy , here I have char * , so means I need also to copy the char * houseName
separately?
what can I do? How can I copy an object that has multiply types like char *
?
and If I had an array ? what could I do ?
typedef struct house
{
int numOfRooms;
char* houseName;
struct house *houses[10];
}HOUSE,*pHOUSE;
how can I copy that?
thank u very much!
You need to copy both the structure as well as all memory that's managed by the structure. Like so:
pHOUSE copy(pHOUSE house)
{
pHOUSE newHouse = malloc(sizeof *newHouse); // allocate
if (pHOUSE)
{
memcpy(newHouse, house, sizeof *newHouse); // or "*newHouse = *house;"
size_t const len = strlen(house->houseName);
newHouse->houseName = malloc(len + 1);
if (!newHouse->houseName) { free newHouse; return NULL; }
strncpy(newHouse->houseName, house->houseName, len + 1);
}
return pHOUSE;
}
As you can see, the error handling with two allocations is already getting very cumbersome. If you had multiple internal allocations, the only way to remain sane is to use goto
s systematically to create the appropriate cleanup points.
Example to illustrate the last point:
struct FooLish
{
char * p1;
char * p2;
char * p3;
};
struct FooLish * copy(struct FooLish const * oldFoo)
{
struct FooLish * newFoo = malloc(sizeof *newFoo);
if (!newFoo) { goto end0; }
{
size_t const len = strlen(oldFoo->p1);
newFoo->p1 = malloc(strlen(len + 1);
if (!newFoo->p1) { goto end1; }
strncpy(newFoo->p1, oldFoo->p1, len + 1);
}
{
size_t const len = strlen(oldFoo->p2);
newFoo->p2 = malloc(strlen(len + 1);
if (!newFoo->p2) { goto end2; }
strncpy(newFoo->p2, oldFoo->p2, len + 1);
}
{
size_t const len = strlen(oldFoo->p3);
newFoo->p3 = malloc(strlen(len + 1);
if (!newFoo->p3) { goto end3; }
strncpy(newFoo->p3, oldFoo->p3, len + 1);
}
return newFoo;
end3:
free(newFoo->p2);
end2:
free(newFoo->p1);
end1:
free(newFoo);
end0:
return NULL;
}