How to modify a string inside a struct in C? - c

I am trying to modify a field inside a struct. I have no trouble doing this with other types (i.e. int, float etc.) but char * is giving me problems. I think I have to do something like:
typedef struct{
char *string_field;
} struct_name;
struct_name *struct_name1;
struct_name1 = (struct_name *) malloc(sizeof(struct_name));
strcpy(struct_name1->string_field, new_string);
printf("New string: %s\n", struct_name1->string_field);
But this gives me a segmentation fault. What reason do you think I would get this problem for? Initially, I thought maybe the char *string_field was not big enough to copy to, but I changed the size of it manually to be of size 100 (more than enough) and I still get this problem.

You reserve memory for your struct, which comprises a pointer to a string, but not the space for a string's content. Reserve memory for the string content and let your struct's pointer point to it; then you can copy newstring's content into that memory:
struct_name1->string_field = malloc(strlen(new_string)+1);
strcpy(struct_name1->string_field, new_string);

Allocate memory for the structure as well as for the string.
In example below there is a room for 63 characters in the string.
Remember to free the allocated memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char *string_field;
} struct_name;
int main()
{
struct_name *struct_name1;
struct_name1 = malloc(sizeof(struct_name));
struct_name1->string_field = malloc(64*sizeof(char));
strcpy(struct_name1->string_field, "new_string");
printf("New string: %s\n", struct_name1->string_field);
free(struct_name1->string_field);
free(struct_name1);
return 0;
}
OUTPUT:
New string: new_string

Related

Do we need to initialize the pointers inside struct

We have pointers inside a struct, do we need to initialize the pointers inside the struct?
I have tried the code below, include this sentence below or not, the code all run well.
(Could some experts give help here? and I read some code, and found seems sometimes initialized, sometimes not, so confused and search/ask here.)
The answer in this link seems not mentioned initialize this pointer inside struct. initializing-a-member-of-a-structure-with-pointers-c
#include "stdio.h"
#include "stdlib.h"
struct part{
int num;
char *name;
};
int main()
{
struct part *p = (struct part*)malloc(sizeof(struct part));
//Include this or not, this code all run well
p->name = (char*)malloc(sizeof(char));
p->num = 1;
p->name = "ss";
printf("%d, %s\n", p->num, p->name);
return 0;
}
No, you should not do that, you are creating a memory leak, because you allocate memory and then forget the pointer value and don't free it.
To remove the memory leak:
p->name = malloc(1); //sizeof char is 1 by definition, and cast not needed
free(p->name);
p->name = "ss";
However, if you look at that, it should be clear that allocating 1 byte of memory, then immediately freeing it, is pointless.
Perhaps you want a copy of the string?
const char *initdata = "ss";
p->name = malloc(strlen(initdata)+1);
strcpy(p->name, initdata);
// Remember to free this at some point
Alternatively, you could use initialize with the string literal, but then you should have const char pointer because string literals are read-only:
struct part{
int num;
const char *name;
};

C string struct with mem allocation included

I am working with a bunch of strings for logging. I want to refactor my code and make a new struct that combines the char, its length and allocated size. The idea is to make my internal string operations smoother and the code nicer to read, whilst assigning each string its own max allocated memory to keep the usage to a minimum but prevent stack overflow. I made this simple example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char *str;
int size;
int max;
} Text;
void defText(Text *text, int max)
{
text->str=(char*) malloc(max * sizeof(char));
text->str="";
text->max=max;
}
int main() {
Text *a;
defText(a,50);
a->str="Test all you want";
printf("OUT: %s %zu %lu",a->str,strlen(a->str),sizeof(a->str));
return 0;
}
The function defText initializes and allocates memory. However, when I check the sizeof the char in my struct, I always get 8, no matter what I set in defText. Is this kind of struct handling strings and their properties together even possible? If so, what is wrong here?
There are several problems in your code, this is an example that cleans up these problems:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char *str;
// you could use size to keep track of the strlen. That's particularly
// desirable if you find yourself calling strlen "a lot", since that
// function recalculates the length every time it's called
int size;
int max;
} Text;
void defText(Text *text, int max)
{
// no need to cast the return of malloc. In fact, sizeof(char) is defined by
// the standard to be 1 so you could take that out also.
text->str=malloc(max * sizeof(char));
// `=` is not the proper way to write strings in C, you must use strcpy
// or something similar. It looks like here you're simply trying to
// create an empty string.
//text->str="";
// per #JohnBollinger's comment, the best thing to do here to create
// an empty string is simply set to the first byte to the NUL
// terminator.
text->str[0] = '\0';
text->max=max;
}
int main() {
Text a; // store this in automatic memory, now the object exists without having to malloc
defText(&a,50); // Use & to pass the address of a to defText
// as mentioned, this is not the proper way to write data to a string in
// C. What you've done here is create a memory leak and point a.str to
// the string literal "Test all you want". Use strcpy (or similar) to
// write that string into the data you actually malloc'ed (using the dot
// operator now since `a` is no longer a pointer)
//a->str="Test all you want";
strcpy(a.str, "Test all you want");
// a.str is a pointer, and will always be 8 bytes on your system no matter
// the size of the memory it points to
printf("OUT: %s %zu %zu",a.str,strlen(a.str),sizeof(a.str));
// clean up allocated memory. Since we're about to exit, there's
// really no need to do this here (the OS will reclaim all allocated
// memory when the process ends), but if you're writing a more
// involved, long-running program, you need to be sure to handle
// memory allocations and deallocations appropriately as needed
free(a.str);
return 0;
}
Demo
The
a->str
is pointer .
the correct answer is
sizeof(*(a->str))

How to store string in a struct array?

How can you store a string in a struct array? My code gave me a segmentation fault when I try this. This also happens with the integer.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
/* get the weight and the object */
struct term{
char term[200]; // assume terms are not longer than 200
double number;
};
int main(void)
{
struct term *new[12];
char word[13]= "hello world";
int num =123;
strcpy(new[0]->term,word);
new[0]->number = num;
char word2[20]= "hello new world";
int num2 =123;
strcpy(new[1]->term,word2);
new[0]->number = num2;
}
struct term *new[12] is an array of pointers, they are uninitialized, in order to store anything there you must make your pointers point to some valid memory location, either by allocating memory for them:
struct term *new[12];
for (int i = 0; i < 12; i++)
{
new[i] = malloc(sizeof **new);
}
Or by othewise assigning them valid struct term variables, i.e.:
struct term st;
new[0] = &st;
Anyway, for such a small array, you could just use a fixed size array, i.e. struct term new[12].
malloc is a heavy function that involves multiple system calls, if you can, you should avoid it.
For better understanding when and where you should use dynamic memory allocation take a look at these:
When and why to use malloc?
When do I need dynamic memory?
There is another problem you should address in your code, char word2[13] = "hello new world" is ill formed, the string is too large for its container. It'll need space for at least 16 chars.
Use empty bounds when assigning strings, i.e. char word2[] = "hello new world", the complier will deduce the needed size for the string, avoiding mistakes like these.
Footnote
new is a reserved keyword in C++, it's used to allocate memory and is the functional equivalent of C's malloc, though it is allowed in C, I would avoid using it to name a variable.

C - malloc and structures, segmentation fault

im trying to make program that stores person's last name and name in a structure that is dynamically allocated and then prints it in terminal. For now i have got "segmentation fault" error after inputing the last name in terminal. How do i make it work? Thanks in advance!
My code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person{
char *last_name;
char *name;
};
struct person *p_person;
int main(void)
{
p_person=malloc(sizeof(struct person));
scanf("%s", p_person->last_name);
scanf("%s", p_person->name);
puts(p_person->last_name);
free(p_person);
return 0;
}
p_person->last_name doesn't point to anywhere. You were accessing memory that you are not even permitted to. You invoke undefined behavior accessing it. Solution would be to allocate some memory dynamically or use char last_name[MAXLEN]; in structure.
Solution 1:
struct person{
char last_name[50];
char name[50];
};
Solution 2:
p_person->last_name = malloc(50);
if( p_person->last_name == NULL){
fprintf(stderr,"error in malloc");
exit(1);
}
In the solution-2,
You should do the same thing for name also.
Free the dynamically allocated memory when you are done working with it.
scanf("%49s", p_person->last_name) One less than the buffer size. When scanf() is finished parsing into a string, it appends NUL terminating character automatically.

Why this program is crashing did i wrongly allocated memory

This program is crashing. Please tell me what's wrong with it. When I use an array instead of a pointer like Name[12] in the structure it doesn't crash. I guess there is some problem in dynamic memory allocation. Help please.
#include <stdio.h>
struct struct_tag
{
int number;
char *Name;
} struct_name;
main()
{
struct_name.number = 34;
char *Name = (char *) malloc(sizeof(char));
strcpy(struct_name.Name,"A");
printf("%d", struct_name.number);
}
You're allocating a single character:
char *Name = (char *) malloc(sizeof(char));
And then never using that memory for anything. You meant to allocate memory for struct_name.Name, undoubtedly. But even if you had done so, you're then filling it with two characters ('a' and '\0'):
strcpy(struct_name.Name,"A");
which will cause an entirely different bug.
You want to say:
struct_name.Name = malloc( 2 );
Since (a) you shouldn't cast the result of malloc() and (b) sizeof(char) is always 1 and (c) you need room for the 0 at the end of your string.
For errors:
You are allocating memeory for *Name however you are not allocating
memory for struct_name.Name. So first thing is you need to allocate memory for struct_name.Name
As you already know that you'll be storing "A" in
struct_name.Name you should allocate memory for 2 char.("A" is string i.e 'A' and '\0')
For warnings:
If you want to use strcpy function include string.h in your code.
Also if you are using malloc include stdlib.h in your code.
Try this fixed code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct struct_tag
{
int number;
char *Name;
}struct_name;
int main()
{
struct_name.number = 34;
struct_name.Name = malloc(sizeof(char)*2); // As you will store "A"
strcpy(struct_name.Name,"A");
printf("%d \t", struct_name.number);
printf("%s \n", struct_name.Name);
return 0;
}
first look code carefully.
char *Name = (char *) malloc(sizeof(char));
strcpy(struct_name.Name,"A");
Hare for what you allocated memory (char *Name) and in which you copied string(struct_name.Name)?
here you not allocate memory for struct_name.Name. Also you have allocate memory for one character and you tried to copy two characters.('A' and '\0').
It should be
struct_name.Name = malloc(2);

Resources