This question already has answers here:
dynamic memory allocation and dynamic array
(2 answers)
Closed 1 year ago.
I have a struct called TCarro with this properties.
typedef struct {
char nome[20];
char placaDoCarro[5];
} TCarro;
And I would like to know how I could allocate this variable struct TCarro *carro; dynamically.
For example, when I use scanf to read the number of cars, how should I allocate some memory so that I could do carro[0]->..., carro[1]->..., ...
To dynamically allocate memory for a struct, the following can be used:
TCarro *carVariable=malloc(sizeof(TCarro)*someNumbers);
, where someNumbers are the number of elements you want to allocate.
From the error you posted in the comment, I assume you tried doing something like:
printf("%d",carVariable);
As you have specified the integer specifier in printf (%d), the compiler expects the function to receive an integer, but you give it a struct TCarro instead.
So now you may be wondering, what specifier can I use to print my carVariable?
C, actually, does not offer such specifier, because structs are types created by the programmer, so it has no idea of how to print it.
What you could do, if you wanted to print your variable would be to print each individual elements of the array.
Something like this:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct{
char nome[20];
char placaDoCarro[5];
}TCarro;
int main(void){
size_t someNumbers=10; //if you want to allocate 10 cars
TCarro *carVariable=malloc(sizeof(TCarro)*someNumbers);
//notice that struct before TCarro is not needed, as you defined it as an existing type (named TCarro)
strcpy(carVariable[0].nome,"Mercedes");
strcpy(carVariable[0].placaDoCarro,"xxxx");
strcpy(carVariable[1].nome,"Ford");
strcpy(carVariable[1].placaDoCarro,"xxxx");
//printf cars
printf("%s %s\n",carVariable[0].nome, carVariable[0].placaDoCarro);
printf("%s %s\n",carVariable[1].nome, carVariable[1].placaDoCarro);
free(carVariable);
return 0;
}
Notice that I used strcpy, because I needed to copy a string to each field of the struct.
Related
This question already has answers here:
How can I correctly assign a new string value?
(4 answers)
Closed last year.
struct student
{
char name[50];
int rollno;
float marks;
};
int main()
{
char nam[50];
int i = 0, n=5;
struct student s1[n];
for(i=0;i<n;i++)
{
nam[i] = s1[i].name;
}
}
In given code, I am unable to copy s1[i].name in nam[i], I tried all the copy function but it's giving me error every time.
This ...
nam[i] = s1[i].name;
... does not make sense because name[i] is one char, whereas s1[i].name is an array of 50 chars. Moreover, your loop is over the number of elements of s1 (5), which is much less than the number of elements of nam or s1[i].name.
Supposing that you really do want s1 to be an array of struct student as opposed to just one struct, you probably want to use strcpy(). However, you might want or need to use memcpy() (or an element by element copy loop) depending on the nature of the contents of s1 and its elements and any artificial requirements on the exercise.
The strcpy() variation would look like this:
strcpy(nam, s1[i].name);
// do something with nam ...
That depends on the source array to contain a null-terminated string, which is not guaranteed to be the case in the demo program, which never puts any data in s1 or its elements.
Use strcpy() I have tried and it's working
Lots of little things working against you in this code, eg the following...
int i = 0, n=5;
struct student s1[n];
...creates a variable length array of struct student, preventing an initializer from being a viable path. But if for the sake of illustration you can live with a non-VLA version, then try this:
//Use a hard-coded to `5`, to create an array of 5 struct student, initialized as shown:
struct student s1[5] = {{"name1"1, 1.0},("name2",2,2.0},{"name3",3,3.0},{"name4",4,4.0},{"name5",5,5.0}};
Next, your current code: char nam[50]; creates a single uninitialized char array, sufficient for containing only 1 string with up to 49 characters, with a terminating \0. If you can, create it like this. (for the sake of learning to copy strings in a loop.)
char nam[5][50] = {{0}};//created 5 elements of null terminated char array elements,
Then you can do this in your loop:
for(i=0;i<n;i++)
{
strcpy(nam[i], s1[i]name);
}
By now (from comments and answers) you should already know that strings cannot be copied using the = operator like integers or floating numbers. String functions such as strcpy(), or sprintf() can be used to populate strings.
hey I am trying to create a program in which I am trying store elements from one array to another with the use of a pointer to pointer but the problem is that is caused undefined behavior I believe that the problem is that I do not pass the elements in members with a proper way
I know it is a vague way of doing this but It is in only for practising reasons
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct student{
char *name;
int *number;
}T;
int main(void) {
char array[10][100]={"araaaa","bbgt","gffkghgh"};
T arr[10][100];
T *p;
T **p1;
p=&arr[0][0];
p1=&p;
int i=0;
for(i = 0 ; i < 3 ; i++)
{ p=arr[i];
strcpy((*p1)->name,array[i]);
}
/*******print_elements*************/
for(i = 0 ; i < 3 ; i++)
{ p=arr[i];
printf("\n the elements are %s",(*p1)-> name);
}
return 0;
}
When you do this:
strcpy ((*p1)->name, array[i]);
(*p1)->name is an uninitialised pointer. What happens, therefore, is in the lap of the gods.
The easiest fix is to modify your student structure such that name is a buffer, rather than a pointer. At the same time, change number to an int, rather than a pointer to an int::
typedef struct student{
char name [100];
int number;
} T;
If you want to keep name as a pointer then you have to allocate some memory before you store your string in it. This should work:
(*p1)->name = strdup (array[i]);
Don't forget to free the memory when done.
T is made of of two pointers, this first one points to a string of characters in memory.
arr is a 2D array that is allocated to store a total of 1000 T structures.
arr[i] would reference a 1D array of T structures within arr
*p1 would essentially be arr[i], since dereferencing p1 gives you p, which was just set to arr[i]. So, that is not a pointer to a T structure, but to an array of T structures. Forcing the cast will likely give you a reference to the first T structure in that row, however.
->name This value is never set. You allocated an array, but "name" is a pointer to memory, not an array of characters, so '->name' is undefined.
I think you need to change arr to be a single dimension array. You aren't using 90% of it.
And, you need to initialize every T struct in that array. You can use malloc or strdup, and then remember to free them all. Or, set the struct to use an array instead.
I'm struggling (again..) with a project in C coding.
Please help me to understand how to access a variable that was dynamically allocated, through 2D array that was also dynamically allocated.
Every attempt ends up with failure, and I can't find the right syntax...
The attempt : putting a string in the family_name pointer in the new Family allocated into **list.
scanf(" %s",&lod->list[0]->family_name);
The program:
#define _CRT_SECURE_NO_WARNINGS
//Libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Consts, globals, structs
#define MAX 10000
typedef struct person
{
char *name;
int gender; //1-female, 0-male
} Person;
typedef struct family
{
char *family_name;
Person *mother, *father; // parents' names
Person **children_list; // list of the children in this family
unsigned child_list_size; // size of child_list array
unsigned current_listChild_size;
} Family;
typedef struct listFamilys
{
Family **list;
unsigned current_listFamily_size; // current size of family
}
ListFamilys;
//main
void main()
{
ListFamilys *lod = (ListFamilys*) malloc(sizeof(ListFamilys));
if(! lod) exit(0);
lod->current_listFamily_size =0;
lod->list = (Family**)malloc(sizeof(Family*));
if (!lod->list) exit(0);
printf("Enter family name: ");
**scanf(" %s",&lod->list[0]->family_name);**
system("pause");
}
The issue here is simply a type error combined with insufficient allocation. In order for this to work you need to allocate space for some Family pointers (which you are doing, though only 1), and then an actual Family element (which you are not doing) and then allocate space for the name (which you are not doing). Basically, the code should be
lod->list = (Family**) malloc(sizeof(Family*));
lod->list[0] = (Family*) malloc(sizeof(Family));
lod->list[0]->family_name = (char*) calloc(11, 1);
where you are only doing the first line of that. My usage of calloc here is somewhat arbitrary, as is the 10 char limit. You can modify as is appropriate.
However, while this is the simplest way to get a single element up and running, this approach collapses at the large scale because of how many allocations you have to do, and deallocating memory becomes a nightmare due to how many separate allocations are made using this approach. Therefore, it is better to allocate say 4kb of space for names to a separate pointer, and then point the name field of persons and families to the relevant name rather than a separate allocation for each of their names. So on with the rest of it. Essentially, try to extract allocations rather than tunnel down with them field after field like the code above does.
This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 5 years ago.
What i intend to achieve with this code is to take a string character from main function, and then assign it to name in structure at a specific index.
Example: It should print for me Name=> Charles Key=> 0
Next line will be Name=> George Key=> 1...and so on. But it rather picks the last name entered and use it for all though my structure is an array of structure. I don't also want to take it direct in the main...like scanf("%s", &node[i].name) because in the real project i am building, i will calculate for i based on the what the user enters. Please help me out. Thanks
#include<stdio.h>
#include<stdlib.h>
typedef struct{
int key;
char *name;
}test;
int main(){
test node[5];
int i;
char see[10];
//for loop for taking string character in see and then assigning name in structure to it
for(i=0; i<5; i++){
printf("Enter name\t");
scanf("%s", &see);
//assigns name in structure index i to see
node[i].name=see;
node[i].key=i;
}
//prints data stored in structure
for(i=0; i<5; i++){
printf("Name=> %s\t\tKey=> %d",node[i].name, node[i].key);
}
return 0;
}
Change as per following...
char *name; ----> char name[10];
scanf("%s", &see); ----> scanf("%s", see);
node[i].name=see; ----> strcpy(node[i].name, see);
You need to malloc space inside the struct and copy the text rather than assigning it. When you assign the pointer you are effectively making the struct's pointer point to the same memory so the next time you read into that memory you overwrite the old value.
Try replacing:
node[i].name = see;
with:
node[i].name = malloc(strlen(see) + 1);
if (node[i].name == NULL)
{
// Handle Malloc error
}
strncpy(node[i].name, see, strlen(see) + 1);
So, the task is to read file and push data to structure. the data file is:
babe 12 red 12
deas 12 blue 12
dsa 12 red 512
bxvx 15 blue 52
reed 18 black 15
while code is something like that
struct shoes {
char name[8];
int size;
char color[8];
int price;
};
//open file
shoes *item=(struct shoes*)malloc(sizeof(struct shoes));
for (i=0; !feof(file); i++) {
item=(struct shoes*)realloc(item,sizeof(struct shoes)+i*sizeof(struct shoes));
fscanf(file,"%s %i %s %i\n",(item+i)->name,(item+i)->size,(item+i)->color,(item+i)->price);
}
but the program crashes every time.
dbg says: No symbol "item" in current context.
where is error?
You code has some bugs:
1) You need a typedef for shoes unless you're compiling with a C++ compiler ... but then you should have tagged this C++.
2) feof doesn't return false until an attempt has actually been made to read beyond the end of file, so your code makes the array of shoes 1 too large.
3) You're passing ints to fscanf instead their addresses.
If compiling as C code, not C++ code, the casts on malloc and realloc aren't necessary and are advised against. And there are other stylistic issues that make you code harder to comprehend than it could be. Try this:
typedef struct {
char name[8];
int size;
char color[8];
int price;
} Shoe;
// [open file]
Shoe* shoes = NULL; // list of Shoes
Shoe shoe; // temp for reading
for (i = 0; fscanf(file,"%s %i %s %i\n", shoe.name, &shoe.size, shoe.color, &shoe.price) == 4; i++)
{
shoes = realloc(shoes, (i+1) * sizeof *shoes);
if (!shoes) ReportOutOfMemoryAndDie();
shoes[i] = shoe;
}
The problem is that you are not passing pointers to the integers you want to read using fscanf, you are passing the integers themselves.
fscanf treats them as pointers. And where do they point? Who knows - the integers were uninitialized, so they could point ANYWHERE. Therefore, CRASH.
Fix thusly:
fscanf(file,"%s %i %s %i\n",
(item+i)->name,
&((item+i)->size),
(item+i)->color,
&((item+i)->price));
Note that you don't need the same for name and color because arrays degenerate to pointers, so you're passing the right thing already.
And please, consider ditching the item+i notation; item[i] is so much clearer and easier to understand when casually reading the code:
fscanf("%s %i %s %i\n",
item[i].name,
&item[i].size,
item[i].color,
&item[i].price);
Are you sure the debugger says that? I'm surprised it even compiled...
You wanted:
struct shoes *item
If you don't proved a typedef of your structure, you have to explicitly say "struct" every time you reference it.
Second note:
item=(struct shoes*)realloc(item...
Don't assign the same pointer from realloc() that you pass into it. If the reallocation fails it will return NULL and that could be killing you. You should make sure you're checking the results of both the initial malloc() and the realloc()
Third point:
You need to be passing the address of the int's to the fscanf().
fscanf(file,"%s %i %s %i\n",(item+i)->name,&((item+i)->size),(item+i)->color,&((item+i)->price));
There are two issues with your code:
1st. The struct:
you could define your struct in two ways,
the way you did:
struct shoe{
char name[8];
int size;
char color[8];
int price;
};
and in this case you should refer to a pointer to it as:
struct shoe *item;
the other (perhaps more convenient?) way using a typedef along with the defenition:
typedef struct {
char name[8];
int size;
char color[8];
int price;
} shoe;
and in this case you should refer to a pointer to it as:
shoe *item;
Therefore the code you posted isn't supposed to compile.
2nd one:
fscanf should be given pointers to integers/chars in the case you showed.
You've correctly passed the char pointer(since you passed the name of a char array which is actually a char pointer to the first element), but you have passed some integers and fscanf needs pointer to integers it is supposed to fill, so your code should be:
fscanf(file,"%s %i %s %i\n",(item+i)->name,&((item+i)->size),(item+i)->color,&((item+i)->price));