Segmentation Fault using pointer of structure - c

When I try to debug my program, I have error message like "Segmentation fault".
typedef struct
{
int a;
char *** tab;
}Operateur;
int main()
{
char * chaine = "test";
Operateur * emptyStruct = (struct Operateur *) malloc(sizeof(Operateur));
emptyStruct->tab[0][0] = * chaine;
return 0;
}
I would like to put the content of chaine in the first place of my array(tab).
Thanks.

The member tab is not initialized, you have to allocate it.
For example:
Operateur * emptyStruct = malloc(sizeof(Operateur));
emptyStruct->tab = malloc(sizeof(char**) * 1);
emptyStruct->tab[0] = malloc(sizeof(char*) * 1);
Change the "1" to allocate a bigger array.

Related

Memory Leak with 2D Char Array

I am trying to free a 2D char array but I'm getting a memory leak when I compile with fsanitize=address and then run the program. It doesn't seem like the code free(innerArray) is freeing the individual char array. Any ideas?
struct Item {
char* line;
struct Item *next;
};
void mainMethod(Item *firstArgument) {
// Create 2d array
int r = 5; // r gets some number
char **myargs = malloc((r+1)* sizeof(char *));
myargs[0] = malloc((strlen(command)+1) * sizeof(char));
myargs[0] = command;
int i = 1;
struct Item* arg = firstArgument->next;
for ( ; i < r; i++) {
myargs[i] = malloc(((strlen(arg->line)+1)*sizeof(char)));
strcpy(myargs[i], arg->line);
arg = arg->next;
}
myargs[i] = NULL;
// do processing ...
// Free 2d array
int i = 0;
while (i <= r) {
char* innerArr = arr[i];
free(innerArr);
i++;
}
free(arr);
}
This allocates a string then replaces it with the address of command:
myargs[0] = malloc((strlen(command)+1) * sizeof(char));
myargs[0] = command;
leaking the allocated memory. If you don't need the copy just use the 2nd line, and if you want a copy either do:
strcpy(myargs[0], command);
Or replace both lines with:
myargs[0] = strdup(command);
As always you want to check if your allocations failed. sizeof(char) is defined as 1 so you just leave it out.

Dynamically resizing a struct in C

I'm fiddling around with Object oriented programming in C (note! Not C++ or C# - just plain ol' C). Right now, I'm trying to dynamically resize a struct (I'm playing with writing a simple String class). The code builds okay:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct TestClass
{
char *s;
size_t size;
size_t b_size;
void (*CreateString) (struct TestClass*,char*);
};
void TestClassCreateString(struct TestClass *m, char* str)
{
char *buf;
m->size = strlen(str);
if (!m->size)
{
free(m->s);
m->s = malloc(16);
}
else
{
buf = realloc(m->s, m->size);
if (buf) m->s = buf;
}
}
struct TestClass* TestClassCreate()
{
struct TestClass* m = malloc((sizeof(struct TestClass)));
m->CreateString = TestClassCreateString;
return m;
}
int main()
{
struct TestClass* fizz = TestClassCreate();
fizz->CreateString(fizz,"Hello World");
free(fizz);
return 0;
}
…But on running it I get the following error:
malloc: *** error for object 0x5000000000000000: pointer being realloc'd was not allocated
*** set a breakpoint in malloc_error_break to debug
Is anyone able to identify where I've gone wrong? Thanks in advance!
malloc does not zero its memory; it returns garbage, so you get an invalid pointer inside this struct:
struct TestClass* m = malloc((sizeof(struct TestClass)));
When creating a struct TestClass in TestClassCreate() the code misses to properly initialise the freshly allocated struct.
So calling
free(m->s);
tries to free memory at a random address, which invokes undefined behaviour and typically crashes the program.
To fix this modify the code as follows
struct TestClass* TestClassCreate()
{
struct TestClass* m = ...
...
m->s = NULL;
m->size = 0;
m->b_size = 0;
return m;
}
To make things better also add some error checking:
struct TestClass* TestClassCreate()
{
struct TestClass * m = malloc((sizeof(struct TestClass)));
if (NULL != m)
{
m->CreateString = TestClassCreateString;
m->s = NULL;
m->size = 0;
m->b_size = 0;
}
return m;
}
To make the code even more fail-safe apply these last changes:
struct TestClass* TestClassCreate(void)
{
struct TestClass * m = malloc(sizeof *m);
...
Further more the code misses to allocate memory for the C-"string"'s 0-terminator here:
void TestClassCreateString(struct TestClass *m, char* str)
{
...
else
{
buf = realloc(m->s, m->size + 1); /* allocate 1 byte more for the trailing
`0` marking the end of a C-"string". */
...
You are short by 1-byte. You need to add 1 to m->size for the null-terminator if you intend to copy str to m->s. E.g.:
void TestClassCreateString(struct TestClass *m, char* str)
{
char *buf;
m->size = strlen(str);
if (!m->size)
{
free(m->s);
m->s = malloc(16);
}
else
{
buf = realloc(m->s, m->size + 1);
if (buf) m->s = buf;
strncpy (m->s, str, m->size + 1);
}
}
Then you can do something like:
int main()
{
struct TestClass* fizz = TestClassCreate();
fizz->CreateString(fizz,"Hello World");
printf ("\n fizz->s : %s\n\n", fizz->s);
free(fizz);
return 0;
}
and get:
$ ./bin/oo_struct
fizz->s : Hello World

how to use malloc () in Double Pointer in Structure in C

I have structs:
typedef struct accont
{
char **tel;//list of tel
char **email;//list of emails
}acc;
and
typedef struct _strcol
{
int count; //total of accounts
acc **list;
} strcol ;
I access the structure with a pointer:
strcol index;
contato *p;
p = (index.list + index.count);
the question, how i use malloc() in this function?
i try:
(*p)->tel = (char **) malloc(i * sizeof (char*))
p.tel = (char **) malloc(i * sizeof (char*))
&(*p)->tel = (char **) malloc(i * sizeof (char*))
and then as I do the second malloc to save data email or tel
my first post, excuse anything
So this:
(*p)->tel = (char **) malloc(i * sizeof (char*))
allocates space to store i pointers to char - so you can have i telephone number strings. But you don't actually have any space allocated to store those telephone number strings themselves yet. To do that, you need (for the first telephone number):
(*p)->tel[0] = malloc(j);
If this call to malloc() succeeds, you can now store nul-terminated string of length j-1 in the space pointed to by (*p)->tel[0]. You can then do the same for the other pointers in (*p)->tel up to (*p)->tel[i-1].
Using malloc() is simple if code follows:
some_type *p;
p = malloc(number_of_elements * sizeof *p);
if (p == NULL) Handle_OutOfMemory();
So with p.tel,
// p.tel = (char **) malloc(i * sizeof (char*));
p.tel = malloc(i * sizeof *(p.tel));
if (p.tel == NULL) exit(EXIT_FAILURE);
I'm going to assume 'p' is acc *p; (i have no idea what 'contato' is).
Anyway ... the point is to show how memory can be allocated & tel/email data stored/accessed ... Also copied tel #/email id simply to demonstrate ...
Regarding casting void pointer returns from malloc, I've seen arguments for/against ... i cast (malloc's about the only case where i cast).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct accont
{
char **tel; //list of tel
char **email; //list of emails
}acc;
typedef struct _strcol
{
int count; //total of accounts
acc **list;
}strcol;
int main()
{
int iNumAccounts = 5; // Assume there are 5 Accounts.
int iNumTels = 2; // Each Account has 2 Tel #s.
int iNumEmails = 3; // Each Account has 3 Email ids.
strcol index;
acc *p = NULL;
index.list = (acc **)malloc(5 * sizeof(acc *)); // Master list
// of 'acc' pointers i.e. pointer to a set of pointers.
int i, j;
for(i=0; i<iNumAccounts; i++) // Go through the 5 Accounts, one at
// a time ... and allocate & store tel #s/email ids.
{
index.list[i] = (acc *)malloc(sizeof(acc));
p = index.list[i];
p->tel = (char **)malloc(iNumTels * sizeof(char*));
for(j=0; j<iNumTels; j++)
{
p->tel[iNumTels] = (char *)malloc(11 * sizeof (char)); // 10 digit tel # + 1 byte for '\0' ...
strcpy(p->tel[iNumTels], "1234567890");
}
p->email = (char **)malloc(iNumEmails * sizeof(char*));
for(j=0; j<iNumEmails; j++)
{
p->email[iNumEmails] = (char *)malloc(51 * sizeof(char)); // 50 char long email id + 1 byte for '\0' ...
strcpy(p->email[iNumEmails], "kingkong#ihop.yum");
}
}
for(i=0; i<iNumAccounts; i++) // Go through the 5 Accounts, one at a time ... and display.
{
p = index.list[i];
for(j=0; j<iNumTels; j++)
{
printf("Tel # is: %d\n", p->tel[iNumTels]);
}
for(j=0; j<iNumEmails; j++)
{
printf("Email id is: %s\n", p->email[iNumEmails]);
}
printf("----------\n");
}
}
If I've understood the case correct, a stack implementation will be best suited in this case. You can use the standard stack library header (of gcc) or create your own stack implementation suited for your own need.
An example may be something like the code below but you'd better follow the Jerry Cain's videos about the stack procedures (you'll find these videos on youtube: Stanford - Programming Paradigms videos. Stack session should be between video number 6 to 8). link from here
note: be careful! Killing stack elements (via StackPop) will not kill the char strings created by strdup. You'll need to free them individually. These are explained in the videos but I don't exactly remember how (again, you'd find some valuable info in those videos for your case).
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef struct {
char *tel;
char *email;
} account;
typedef struct {
int *ptrElement; // starting address of the stack
int sizeAllocat; // total size allocated
int sizeCurrent; // current size
int sizeElement; // byte length of the stack element
} Stack;
// create a new stack pointer
void StackNew (Stack *s, int sizeElement) {
assert (s->ptrElement > 0);
s->sizeElement = sizeElement;
s->sizeCurrent = 0;
s->sizeAllocat = 4;
s->ptrElement = malloc (4 * sizeElement);
assert (s->ptrElement != NULL);
}
// kills a stack pointer
void StackDispose (Stack *s) {
free (s->ptrElement);
}
// expands stack space
static void StackGrow (Stack *s) {
s->sizeAllocat *= 2;
s->ptrElement = realloc (s->ptrElement, s->sizeAllocat * s->sizeElement);
}
// insert new stack pointer (of type account for example)
void StackPush (Stack *s, void *ptrElement) {
if (s->sizeCurrent == s->sizeAllocat) {
StackGrow (s);
}
void *target = (char *) s->ptrElement + s->sizeCurrent * s->sizeElement;
memcpy (target, ptrElement, s->sizeElement);
s->sizeCurrent++;
}
// pops (deletes) an element from stack
void StackPop (Stack *s, void *ptrElement) {
void *source = (char *) s->ptrElement +
(s->sizeCurrent - 1) * s->sizeElement;
memcpy (ptrElement, source, s->sizeElement);
s->sizeCurrent--;
}
// relocate stack element
void StackRotate (void *first, void *middle, void *after) {
int foreSize = (char *) middle - (char *) first;
int backSize = (char *) after - (char *) middle;
char tmp [foreSize];
memcpy (tmp, first, foreSize);
memmove (first, middle, backSize);
memcpy ((char *) after - foreSize, tmp, foreSize);
}
int main () {
Stack s;
account *acc;
StackNew (&s, sizeof (acc));
// your code here
// example
// acc->tel = strdup("some number");
// acc->email = strdup("some text");
// StackPush(&s, &acc);
...
// StackPop(&s, &acc);
...
...
StackDispose (&s);
return 0;
}

Filling dynamic array of structs in C

I allocate array of struct in function, but cannot fill those structures with values in same function.
#include<sys/sem.h>
void setSemaphores(int N, struct sembuf **wait){
*wait = malloc(N * sizeof(struct sembuf));
wait[3]->sem_op = 99; //causes error: Segmentation fault (core dumped)
}
int main(int argc, char *argv[]) {
int N = 4;
struct sembuf *wait;
setSemaphores(N, &wait);
wait[3].sem_op = 99; //works fine
return 0;
}
In setSemaphores():
wait is a pointer to one variable of type struct sembuf, not to an array of them.
Thus, wait[3] is UB. What you wanted is (*wait)[3].sem_op.
Another tip:
Change *wait = malloc(N * sizeof(struct sembuf));
to *wait = malloc(N * sizeof **wait);.
That easily avoids using the wrong type in a sizeof.

How do I make a struct containing a dynamic array of strings in C?

I have three files: header.h, machine.c, and main.c
How do I create a struct containing a dynamic array of strings?
How do I fill the strings using functions in machine.c?
How do I print that dynamic array of string?
My header.h file:
typedef struct smp * alamat;
typedef struct smp{
int jd;
int level;
char c[100];
char * words;
alamat sibling;
alamat child;
}simpul;
I want to add a dynamic array of strings into variable words in that struct. My machine.c file looks like this:
void addChild(char c[], char *dosa, int n, simpul* s){
int i;
if(s != NULL){//simpul tidak kosong
dosa = malloc(n * sizeof(char*));
simpul* baru = (simpul*)malloc(sizeof(simpul));
strcpy(baru->c,c);
baru-> jd = n;
baru->words = dosa;
if(s->child == NULL){//tidak punya anak
baru->child = NULL;
baru->sibling = NULL;
s->child = baru;
}else if(s->child->sibling == NULL){//anak cuma 1
baru->child = NULL;
s->child->sibling = baru;
baru->sibling = s->child;
}else{//anak banyak
simpul * terakhir = s->child;
while(terakhir->sibling != s->child){
terakhir = terakhir->sibling;
}
terakhir ->sibling = baru;
baru->child = NULL;
baru->sibling = s->child;
}
}
}
My main is like this to pass the array of string to the machine.c:
impul * node = findSimpul(penanda,t.root);
char *string = (char *) malloc( (n* sizeof(char)));
for(k=0;k<n;k++){
scanf("%s",&string[k]);
}
addChild(anak,string,n,node);
How do I solve these problems?
You need an array of pointers.
char **strings;
int nmemb = 1;
strings = calloc(nmemb, sizeof(*char));
strings[0] = calloc(your_str_len, sizeof(char));
// now you have allocated space for one string. in strings[0]
// let's add another
nmemb = 2;
strings = realloc(strings, sizeof(*char) * nmemb);
strings[1] = calloc(your_2nd_str_len, sizeof(char));
// now you are ready to use the second string in string[1]

Resources