c basic struct help needed - c

I want to copy values into a struct using a pointer.
I keep getting segmentation fault from this small piece of code.
struct companyInfo
{
double sharePrice;
char companyName[100];
};
int main()
{
struct companyInfo * pdata = NULL;
strcpy(pdata->companyName, "sdfsd");
exit(0);
}

You aren't allocating any space for the struct, just a pointer that is null.
struct companyInfo * pdata = NULL;
pdata = calloc( 1, sizeof(struct companyInfo) );
if( pdata != NULL )
{
strncpy(pdata->companyName, "sdfsd", sizeof(pdata->companyName) - 1);
}
Note: calloc() will also zero out the memory for you, as opposed to malloc() which will just allocate. Also, you should check the return of these functions to make sure the pointer is not NULL.
Important: Any memory allocated using malloc(), calloc(), ex.. needs to be explicitly freed.
Example:
if( pdata != NULL )
{
free( pdata );
}
exit(0);

companyInfo is a pointer to a struct, and that pointer is pointing to NULL. So when you try to dereference it, you get the seg fault. You either need to use malloc to allocate some space for the struct pointer to point to, or declare the struct on the stack.
For the purposes of your exercise, I would go with option 2, as it's simpler. Just do:
int main()
{
struct companyInfo pdata;
strcpy(pdata.companyName, "sdfsd");
exit(0);
}
Because there is no * after companyInfo, pdata is not a pointer to a struct, but a struct.

Try this:
int main() {
struct companyInfo pdata;
pdata.companyName = "sdfsd";
}
You can set all variables in the struct at once:
struct companyInfo pdata = { 2.3425, "company" };
Tip: Use typedef before using a struct:
typedef struct companyInfo companyInfo;
So you don't have to type "struct companyInfo" every time. You can now simply use:
companyInfo pdata;
Hope I helped :)

The problem isn't with using a struct, but with trying to use a null pointer. Try something like this:
struct companyInfo *pdata = malloc(sizeof(*pdata));
strcpy(pdata->name, "sdfsd");

Related

Passing a struct to void* param then copying it to a void*, reconstructing gives garbage value

I am really confused with passing my struct to void pointers, I'm not sure which one can be assigned directly and which one should be memcpyed, I've tried a lot of combinations but it does not seem to work. Any help would be very appreciated!
This is my C code
struct SomeStruct {
int a;
char name[10];
};
void *randoms[10];
void transferFunction(void* data, int index) {
// This function copies data to randoms[index]
// I would like to have the whole struct's data in randoms[index]
memcpy(&randoms[index], data, sizeof(struct SomeStruct));
}
struct SomeStruct *ss = malloc(sizeof(struct SomeStruct));
ss->a = 1;
strcpy(ss->name, "abc");
transferFunction(ss, 0);
My goal is to have the randoms[index] having the struct's data as another function is going to read from it, as shown below, but I am unable to retrieve the struct data correctly, it gives me some garbage value
void readFunction() {
struct *SomeStruct ss = malloc(sizeof(struct SomeStruct));
memcpy(ss, &randoms[index], sizeof(struct SomeStruct));
printf(ss->name);
}
Does anyone knows how to solve this problem? Thank you very much!!!
You can not "copy in to a void".
A void * can contain a memory address, but does not contain any information about the size of the data at that address.
Also, it can not contain any data, only an address!
In this line:
void *randoms[10];
You create an array that can hold 10 addresses.
You never initialize this array, so it will start out all zeroes (this only works for global variables in C).
You can put the address of your structure in to the array, like so:
random[0] = (void*)ss;
However, this does not transfer any data, so if you free the original structure (ss) your data is gone, and the address in random[0] is illegal.
If you want to transfer data you need to create array of struct SomeStruct or you need to allocate another SomeStruct, store its address in random[0] then memcpy to that address.
void transferFunction(void* data, int size, int index)
{
randoms[index] = malloc(size);
if (randoms[index] != NULL) {
memcpy(randoms[index], data, size);
}
}
Your code has some problems:
struct *SomeStruct ss = ... should be struct SomeStruct *ss =.
You are not cheking the return value of malloc() (which may fail).
You are not freeing ss allocated with malloc(). You should call free() on ss.
My goal is to have the randoms[index] having the struct's data
Lev M.'s answer already answers this part.
as another function is going to read from it
Simply assign your void pointer to a SomeStruct pointer:
void readFunction(int index)
{
if (index >= 10) // Index out of range
return;
struct SomeStruct *ss = randoms[index];
printf("%s\n", ss->name);
}

Learning dynamic memory allocation

i am a student and i try to teach myself code.
My question:
i have two structs:
struct1{
int a;
char name[20];}
struct 2{
struct struct1 *objekt;
int number;
double dNumber;}
I wanted to dynamically allocate memory in order to create at least one new Objekt(for lack of a better word). I know for example that i can allocate memory by using malloc or calloc. Which is fine. But how can i add a new object dynamically and via the console input, without defining a new struct? I am a complete novice and sorry. Thank you.
Consider the following example:
#include <stdio.h>
#include <stdlib.h>
struct Struct {
int a;
char name[20];
};
struct Struct struct1;
int main()
{
struct Struct *struct1_p;
struct1_p = &struct1;
struct1.a = 1;
printf("struct1->a = %d\n", struct1_p->a);
// Now let's create new structure dynamically
struct Struct * struct2 = malloc(sizeof(struct Struct));
// Now check if the allocation succeeded?
if(struct2 != NULL) {
//Success
//struct2 now is a pointer to the memory which is reserved for struct2.
struct2->a = 2;
} else {
// Allocation failed
}
printf("struct2->a = %d\n", struct2->a);
return 0;
}
This way, having the type of the desired object, you can dynamically create new object in the memory. Accessing the newly created object via pointer returned by malloc.
Remember that malloc returns void*, no need for explicitly cast.

Dynamic memory allocation of struct in c

Code:
struct T_Name
{
char *First;
char *Middle;
char *Last;
};
struct T_FullName
{
char *Title;
struct T_Name Name;
char *Suffix;
};
struct T_Person
{
struct T_FullName *FullName;
int Age;
char Sex;
struct T_Person *BestFriend;
};
typedef struct T_Person *ptrPerson;
ptrPerson pFriend[10];
struct T_Person Person[10];
How could I write necesarry code to dynamically allocate memory to store a value in pFriend[2]->FullName->Name.First?
Assuming you know the length of the first name to store,
// Allocate memory for FullName.
Person[2].FullName = malloc(sizeof(T_FullName);
// Allocate memory for the first name.
Person[2].FullName->Name.First = malloc(FIRSTNAME_LENGTH);
Your pFriend is a pointer variable, so you have to allocate memory for pointer variable first. Then after allocation of the memory again your FullName is pointer type , so we need to allocate memory for it, Finally your Name member in FullName is not a pointer type , so you can use First from Name with a . operator to allocate memory for it.
//Allocate space for T_Person
pFriend[2] = malloc(sizeof(T_Person);
//Allocate space for FullName
pFriend[2]->FullName = malloc(sizeof(T_FullName);
//Allocate space for First Name
pFriend[2]->FullName->Name.First = malloc(sizeof(urstringlength));
pFriend[2] = malloc( sizeof *pFriend[2] );
pFriend[2]->FullName = malloc( sizeof *pFriend[2]->FullName );
pFriend[2]->FullName->First = malloc( strlen(the_name) + 1 );
strcpy(pFriend[2]->FullName->First, the_name);
Note that you probably don't actually want to do this, it will be difficult to use this jumble of structures. You should at least set pointers which aren't in use to NULL , so that your other code can tell which pointers point to allocated memory and which ones don't.
Also, Person is unused in this example. If you wanted pFriend[i] to point at Person[i] you have to say that explicity; replace my first line with:
pFriend[2] = &Person[2];

C Strings in Structs

I want my struct to carry a string. I defined it like so:
typedef struct myStruct {
char* stringy
} myStruct
and a function
free(char *stringy){
//structObj is a struct object
structObj->stringy = stringy
}
Is this correct? I have a feeling that since it's a local variable, stringy will be lost, and the pointer will point to garbage.
Sorry, new with C.
It would be garbage if you were somehow using char** stringy, but structObj->stringy = stringy means "you know the thing that stringy points to? Now structObj->stringy points to that". Of course, it is still possible to unset the value which the pointer is pointing to, and at that point dereferencing will yield garbage.
Here's an example to make it clearer:
#include<stdio.h>
typedef struct mStruct {
char* stringy;
} myStruct;
myStruct * structObj;
void doSomething(char* stringy)
{
structObj->stringy = stringy;
}
int main(int argc, char* argv)
{
char* a = "abc\n";
structObj = malloc(sizeof(myStruct));
doSomething(a);
a = "qxr\n";
printf(structObj->stringy);
}// prints "abc\n"
If stringy is defined in callers of free function, as long as they keep the actual string in its place (where stringy points), no problem.
There is not any local variable declaration in your code.
You have to declare:
typedef struct myStruct {
char* stringy
} myStruct;
free(char *stringy){
myStruct *structObj;
structObj->stringy = stringy;
}
Pay attention to the semicolon that I've added to the end of the typedef declaration.
This was not not in your code.
The object structObj is a struct whose type is myStruct.
Now, your parameter stringy comes from another site, it is not lost.
But the struct structObj will have duration only inside your "free" function.
EDIT
I have fixed an error: the right declaration has to be "pointer to structObj", which is done in this way:
myStruct *structObj;
Observe that now myStruct is a non-initialized pointer, so the following assignment is legal:
structObj->stringy = stringy;
but will not work.
However I think this goes beyond the scope of the original question...
myStruct is type which you defined for your struct myStruct .that to you need to create an object before using.
you need to do like this:
typedef struct myStruct {
char *stringy;
} myStruct_t; //user defined data type
myStruct_t *obj;
// you need to allocate memory dynamically.
obj= (myStruct_t *) malloc(sizeof(myStruct_t));
usage:
scanf("%s",obj->stringy);
printf("%s",obj->stringy);
in function:
my_free(char *str) //str is local string
{
obj->stringy=str;
}
your can also try this code :
typedef struct myStruct {
char stringy[20]; //char *stringy
} myStruct_t; //user defined data type
myStruct_t obj; //object creation
usage:
scanf("%s",obj.stringy);
printf("%s",obj.stringy);
in function:
my_free(char *str) //str is local string
{
strcpy(obj.stringy,str);
}
You're correct that as soon as what it points to goes out of scope, it will point to garbage: this is a dangling pointer. You'll need to allocate some memory and perform a copy to fix this:
add_string(my_struct* s, const char* c)
{
size_t len = strlen(c);
s->file = malloc(len + 1);
strcpy(s->file, c);
}
Don't forget that you'll need to free it when you're done:
void destroy_struct(my_struct* s)
{
free(s->file);
free(s);
}

What's wrong in this allocation?

This the struct that I declared :-
struct page_table_entry {
struct addrspace* as;
vaddr_t va;
//page_state_t state;
int timestamp;
};
Now I want to dynamically allocate memory for an array of this. My implementation is here :-
struct page_table_entry **coremap = (struct page_table_entry**)
kmalloc(npages*sizeof(struct page_table_entry*));
int i;
for(i=0;i<npages;i++)
{
coremap[i] = (struct page_table_entry*)kmalloc(sizeof(struct page_table_entry));
coremap[i].va=(firstAddress+(i*PAGE_SIZE));
}
Its giving me an error on the last line where I am accesing the variable va. Error is:-
error: request for member `va' in something not a structure or union
You have an array of pointers to structs, not an array of structs.
In the line
coremap[i] = (struct page_table_entry*)kmalloc(sizeof(struct page_table_entry));
you cast your memory allocation to page_table_entry*, so coremap[i] is this pointer.
You access the actual struct via
coremap[i]->va=(firstAddress+(i*PAGE_SIZE));
coremap is a pointer to a pointer to a struct page_table_entry.
When you dereference it with coremap[i] you get a pointer to a struct page_table_entry.
You cannot use . on a pointer to a structure. You must use ->:
coremap[i]->va=(firstAddress+(i*PAGE_SIZE));
or
(*coremap[i]).va=(firstAddress+(i*PAGE_SIZE));
Aside from the obvious change to coremap[i]->va, you could change to an array of structs:
struct page_table_entry *coremap = (struct page_table_entry*)kmalloc(npages*sizeof(struct page_table_entry));
int i;
for(i=0;i<npages;i++)
{
coremap[i].va=(firstAddress+(i*PAGE_SIZE));
}

Resources