i have a problem with the allocation of a dynamic struct array.
The struct is composed of a char* field, that is another dynamic array of char. After i allocate all arrays, windows block the program when i try to modifty a struct content. Code:
typedef struct
{
char *cod;
}code;
void create_cod(code *singleCode,int codeLength);
void create_codes(code *codes, int codesNumber, int codeLength);
int main()
{
int codesNumber=4, codeLength=10;
code *codes;
create_codes(codes, codesNumber, codeLength);
codes->cod = "abcd"; /*Windows block the program here*/
}
void create_cod(code *singleCode,int codeLength)
{
singleCode->cod = (char*)malloc(codeLength*sizeof(char));
return;
}
void create_codes(code *codes, int codesNumber, int codeLength)
{
codes= (code*)malloc(codesNumber*sizeof(code));
int i=0;
while(i<codesNumber)
{
create_cod(codes+i,codeLength);
i++;
}
return;
}
Related
I'm doing dining-philosopher problem in C for assignment. And got stuck very begining of my code.
I decided each philosopher to be structure, and forks to be int array.
But I can't use global variable in this assignment.
So, I have to include shared variable in philosopher structure to pass them for arguments of thread routine.
Here is my problem - how to include int array in structure if I can't know proper size of them when initializing?
My plan is just include pointer variable in structure then allocate array's address using &.
But It doesn't work :
#include <stdlib.h>
/* inside structure*/
typedef struct s_share {
int **forks;
} t_share;
/* outside structure */
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
/* malloc structure arrary philo, size = 10 */
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
/* malloc int arrary forks, size = 100 */
forks = (int *)malloc(sizeof(int) * 100);
while (i < 10)
{
philo[i].share->forks = &forks; //error
i++;
}
}
Output : segmentation fault
I tested share->forks size like this :
printf("size of forks : %ld\n", sizeof(philo->share->forks));
Output was 8.
It's enough size to store int * pointer.
Through this I know It's not the memory allocation problem.
Then what is problem? Can someone check this for me?
Edit :
When I try to malloc directly philo->share->forks, I got same error.
typedef struct s_share {
int *forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
while (i < 10)
{
philo[i].share->forks = (int *)malloc(sizeof(int) * 100); //error
i++;
}
}
I thought it's because when philo initialized, sizeof operator calculated forks's memroy to be 8 - which required for pointer.
Is there something wrong?
Edit 2 :
To clear my question,
It's easy to solve this problem, if I write size of array in structure definition.
typedef struct s_share {
int forks[100];
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
but according to my assignmet I have to get philosopher's number from cmd. So I can't do that.
Above is simple version of my origin code
Sorry, Edit 2 is wrong :
typedef struct s_share {
int forks[100];
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
t_share *share;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
while (i < 10)
{
philo[i].share->forks[i] = 1;
i++;
}
}
Output
zsh: segmentation fault ./a.out
I still got segfault when I write array size in struct definition.
I used calloc to initialize all member in my struct but same error occurs :
typedef struct s_share {
int **forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
t_share *share;
int *forks;
int i;
i = 0;
philo = (t_philo *)calloc(10, sizeof(t_philo));
forks = (int *)calloc(100, sizeof(int));
while (i < 10)
{
philo[i].share->forks = &forks; //error
i++;
}
}
Edit 4:
I finally found error. It's because I didn't malloc 'share' struct in philo struct
typedef struct s_share {
int **forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
forks = (int *)malloc(sizeof(int) * 100);
while (i < 10)
{
philo[i].share = (t_share *)malloc(sizeof(t_share)); //here
philo[i].share.forks = &forks;
i++;
}
}
That one line -allocating struct share- solved problem.
Or, I can modify philo struct definition like this :
typedef struct s_philo {
t_share share; //not pointer, just struct
} t_philo;
In this way, I can automatically malloc struct share.
I got confused in this point. Thanks for helping!
this line
philo[i].share->forks
Is dereferencing the pointer 'share' which is not set. You called malloc and did not set any values, so the data inside your allocated buffer is 'garbage' data.
// add begin
t_share* new_share = (t_share*)malloc(sizeof(t_share));
philo[i].share = new_share;
// add end
// don't use &forks
philo[i].share->forks = forks; //error
i++;
// need forks++
forks++;
I have a struct defined like this:
typedef struct {
char id[20];
char descrizione[250];
char tipoSet[30];
int scatoleDisponibili;
float costo;
} Set;
I have another struct called Complex in which I want a field to store an array of only Set struct IDs.
typedef struct {
char idComplesso[20];
content[10];
int dimLogica;
} complex;
So, I want the content array (of max size 10) to be able to store only the string id from a max of 10 Set.
How could I do this in C?
typedef struct {
char id[20];
char descrizione[250];
char tipoSet[30];
int scatoleDisponibili;
float costo;
} Set;
typedef struct {
char idComplesso[20];
int dimLogica;
size_t nsets;
char *content[];
} complex;
complex *assign(Set *s, size_t nsets)
{
complex *cml = malloc(sizeof(*cml) + nsets * sizeof(cml -> content[0]));
/* allocation check */
cml -> nsets = nsets;
for(size_t i = 0; i < nsets; i++)
{
cml -> content[i] = s[i].id;
}
return cml;
}
You'll have to make the content array be an array of char* and when you create the structure only accept id from a Set struct.
Something like this:
complex* createComplex(Set* sets) {
complex* comp = (complex*)malloc(sizeof(complex));
for (int i=0; i<10; i++) {
comp->content[i] = sets[i].id;
}
return comp;
}
And don't let any other function create the comp struct
I just start to learn pointers to structures and I'm confused.I have to create a type of data ARRAY (which is associated with an array which contains integers.) like a structure which contains: numbers of array's elements and the array's elements stored in a part of memory(heap), dynamically allocated.
So I wrote:
typedef struct ARRAY
{
int nrElem; // number of elements
int *v[100];
};
Now I need to create 2 functions, one for reading an array from keyboard and the second one to display it using the structure I declared.
I tried but I get stuck.
void arrayDisplay(ARRAY *ps)
{
int i;
for(i=0;i<pd->nrElem;++i)
{
printf("%d",)
}
}
void readArray(ARRAY *ps)
{
int i;
for(i=0;i<pd->nrElem;++i)
{
printf("%d",)
scanf("%d",&);
}
}
How to continue?
Instead of an array of pointers int *v[100]; you need an array of ints int v[100]; in your data structure.
See code below:
#include <stdio.h>
#include <stdlib.h>
typedef struct ARRAY
{
int nrElem; // number of elements
int v[100];
} ARRAY;
void arrayDisplay(ARRAY *ps)
{
int i;
for(i=0;i<ps->nrElem;++i)
{
printf("%d\n", ps->v[i]);
}
}
void readArray(ARRAY *ps)
{
int i;
for(i=0;i<ps->nrElem;++i)
{
printf("%d: ", i);
scanf("%d",&ps->v[i]);
}
}
int main()
{
ARRAY a;
a.nrElem = 5;
readArray(&a);
arrayDisplay(&a);
return 0;
}
If you really want to use an array of int pointers you need to allocate the array first. And a different level of redirection for printf and scanf. But I'm not sure why you want to allocate memory for an integer array like this.
typedef struct ARRAY
{
int nrElem; // number of elements
int *v[100];
} ARRAY;
void arrayDisplay(ARRAY *ps)
{
int i;
for(i=0;i<ps->nrElem;++i)
{
printf("%d\n", *ps->v[i]);
}
}
void readArray(ARRAY *ps)
{
int i;
for(i=0;i<ps->nrElem;++i)
{
printf("%d: ", i);
scanf("%d",ps->v[i]);
}
}
int main()
{
ARRAY a;
int i;
a.nrElem = 5;
for(i=0;i<a.nrElem;++i) {
a.v[i] = (int*)malloc(sizeof(a.v[i]));
}
readArray(&a);
arrayDisplay(&a);
return 0;
}
This is my code in which if student marks is greater than 85,scholarship status will be changed to sanctioned, but after updating it is not printing
#include<stdio.h>
#include<string.h>
struct scholor
{
char name[25];
int sem;
int marks;
char status;
};
void sanction(int m, char *s)
{
if(m>85)
{
char p[15]="sanctioned";
char *r;
r=p;
while(*r!='\0')
{
*s=*r;
s++;
r++;
}
*s='\0';
}
}
int main()
{
struct scholor s1;
scanf("%s%d%d%s",&s1.name,&s1.sem,&s1.marks,&s1.status);
sanction(s1.marks,&s1.status);
printf("%s",s1.status);
}
status is a single char but you are storing a string into it, effectively doing out of bounds access (undefined behaviour). Change it to an array and then you'll be able to copy.
struct scholor
{
char name[25];
int sem;
int marks;
char status[128];
};
and adjust the calls and passing (since status is an array now -- its name gets converted into a pointer t its first element when passed to functions):
scanf("%s%d%d%s",s1.name,&s1.sem,&s1.marks,s1.status);
sanction(s1.marks,s1.status);
printf("%s",s1.status);
Other suggestions:
1. Use a standard prototype for main such as: int main(void)
2. You could usr strcpy to copy the string as opposed to doing it yourself.
Your struct should have status as a character array not a character .Moreover when you scanf an array dont write & before because the name itself points to the assdress of the first element.Your corrected program is :
struct scholor
{
char name[25];
int sem;
int marks;
char status[16];
};
void sanction(int m, char *s)
{
if(m>85)
{
char p[15]="sanctioned";
char *r;
r=p;
while(*r!='\0')
{
*s=*r;
s++;
r++;
}
*s='\0';
}
}
int main()
{
struct scholor s1;
scanf("%s%d%d%s",s1.name,&s1.sem,&s1.marks,s1.status);
sanction(s1.marks,s1.status);
printf("%s",s1.status);
}
I just wrote some C code:
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct {
void **data;
time_t lastModified;
} container;
container *container_init() {
container *c = malloc(sizeof(container));
void *data = NULL;
c->data = &data;
c->lastModified = time(NULL);
return c;
}
void *container_getData(container *c) {
void **containerData = c->data;
return *containerData;
}
// only pass manually allocated data that can be free()'d!
void container_setData(container *c, void *data) {
free(container_getData(c));
c->data = &data;
}
void container_free(container *c) {
free(container_getData(c)); // <--- THIS LINE
free(c);
}
int main(int argc, const char *argv[]) {
for (int i = 0; i < 100000000; i++) {
char *data = strdup("Hi, I don't understand pointers!");
container *c = container_init();
container_setData(c, data);
container_free(c);
}
}
My logic was the following: When I call container_setData(), the old data is free()'d and a pointer to the new data is stored. That new data will have to be released at some point. That happens for the last time during the call to container_free().
I have marked a line in the container_free() function. I would have sworn I'd need that line in order to prevent a memory leak. However, I can't use the line ("object beeing freed was not allocated") and there's no memory leak if I delete it. How does the string from my loop ever get released?!
Could someone explain where the error is?
c->data = &data;
stores the address of the pointer data (the argument to your function), not the actual pointer. I.e., you're storing a pointer to a temporary.
You could have built the container structure with just a void *data member.
To explain larsmans answer with code make these changes:
typedef struct {
void *data;
time_t lastModified;
} container;
void *container_getData(container *c) {
return c->data;
}
void container_setData(container *c, void *data) {
free(c->data);
c->data = data;
}
void container_free(container *c) {
free(c->data);
free(c);
}
And other changes too -- this just gets you on the right track.