I want to store a string in char array I am trying to do so by using a memcpy() but I am getting a segmentation fault. Can someone explain why? And what could be the correct way of doing this.
What would be better to use char * name; or char name[100]; ?
#include <stdio.h>
struct A
{
char * name;
};
typedef struct A A ;
int main()
{
A *a;
memcpy(a->name,"hello",sizeof(A));
printf("The value of name is %s",a->name);
return 0;
}
You have to allocate memory for structure and it's member and then after you can do copy data in it.
A *a = malloc(sizeof(A));
a->name=malloc(100); //change the size other then 100 what ever you want.
In first place you are asking two questions. You should read a bit here in order to understand how to ask good questions and get good answers.
You get segmentation fault because you haven't allocated memory for you variable name. The fastest way to solve this according the code and description you have provided is to use char name[100] in your declaration. Bear in mind that this is not the only possible way to do things. It depends what you are doing.
struct A
{
char name[100];
};
Then you have to allocate memory for the A *a pointer you are declaring. Better would be to use a normal variable A a and then access the member with the point operator (not sure if that is really an operator but the correct words doesn't come to mind at the moment). A simple snippet would be:
...
A a;
memcpy(a.name, "hello", 6);
printf("The value of name is %s",a.name);
...
A bit of documentation doesn't harm: memcpy()
Related
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.
This question already has an answer here:
Definitive List of Common Reasons for Segmentation Faults
(1 answer)
Closed 2 years ago.
I am just trying to understand why i get a segmentation fault when I use char *name as the member of the struct name... as apposed to char name[30] as the member, which works properly.
thankyou.
struct name
{
char *name1; // if i make this char name[30]; it works properly
};
void name_prompt(struct name *ptr)
{
printf("name: ");
scanf("%s", ptr->name1);
}
int main ()
{
struct name dylan;
struct name *ptr = &dylan;
name_prompt(ptr);
printf("%s", dylan.name1);
}
char name[30]; actually allocates 30 bytes of space within the struct for reading into. char* name just declares name as a pointer, saying that it could possibly be pointing to allocated space, but not necessarily. You never actually allocate space, so it segfaults.
On a side note, you should use %30s instead of %s for security reasons. (see here)
With a char*, you don't actually have any memory allocated to hold the data you're reading in. You didn't initialize the pointer, so it's pointing to some (semi-)random place, and writing to where it points is undefined behavior, so anything can happen.
If you want it to work with a char*, you'd need to malloc some storage for the pointer to point to (ideally freeing it when you're done), e.g.
int main ()
{
struct name dylan;
dylan.name = malloc(50); // Allocates space for up to 49 characters plus a NUL terminator; limit the scanf to match
name_prompt(&dylan);
printf("%s", dylan.name1);
free(dylan.name); // Release the memory
}
Using the array means the struct itself contains the memory wherever the struct was placed (so the struct is much larger, but doesn't rely on additional memory being allocated to be fully functional), in this case on the stack.
Very confused on why I'm getting a "Segmentation Fault (core dumped)".
const int bufSize = 32;
char* splitStrings[bufSize];
splitStrings[0][0] = 'a';
splitStrings[0][1] = '\0';
printf("testchar: %c",splitStrings[0][0]);
printf("teststr: %s",splitStrings[0]);
Thanks for any help
You missed a layer of declaration. You have a table of pointer on char splitStrings. Then you would need to book some memory space and point to it using your pointer. Here is the example for the first pointer:
splitStrings[0] = malloc(2*sizeof(char));
splitStrings[0][0] = 'a';
splitStrings[0][1] = '\0';
printf("testchar: %c",splitStrings[0][0]);
printf("teststr: %s",splitStrings[0]);
Read how malloc is working and especially how to de-allocate memory with free once your done to avoid memory leak.
I think you want to define a 2-D char array.
To do this make these steps:
First
Define a char** array of pointers.
char **splitStrings[bufSize];
Second
Allocate memory for row:
splitStrings = malloc(bufSize*sizeof(char*));
Third
For each row allocate memory for its columns.
for (int i=0;i<bufSize;i++){
splitStrings[i]=malloc(bufSize*sizeof(char*));
}
Code
#include <stdio.h>///for printf()
#include <stdlib.h>///for malloc()
int main(void){
const int bufSize = 32;
char **splitStrings;
splitStrings = malloc(bufSize*sizeof(char*));
for (int i=0;i<bufSize;i++){
splitStrings[i]=malloc(bufSize*sizeof(char*));
}
splitStrings[0][0] = 'a';
splitStrings[0][1] = '\0';
printf("testchar: %c\n", splitStrings[0][0]);
printf("teststr: %s\n", splitStrings[0]);
free(splitStrings);
return 0;
}
Further Notes
For more information about 2-D dynamic array see
By using malloc() function in C never cast the result of it see
After allocating dynamic memory in Heap never forget to release it by using free().
I suggest you read more about how to allocate dynamic memory in C with malloc() function.
Last Edition on code
Change malloc(bufSize*sizeof(char)); to malloc(bufSize*sizeof(char*)); this is true way of allocating memory
Because in first case calling free() on splitStrings pointer cause memory error. Why?
char* splitStrings[bufSize]; //is expecting address, if it is derefencing directely will through segmentation fault.
we have two options one is dynamic memory allocation otherwise declare like below.
#include<stdio.h>
void main()
{
const int bufSize = 32;
char splitStrings[1][bufSize];
splitStrings[0][0] = 'a';
splitStrings[0][1] = '\0';
printf("testchar: %c",splitStrings[0][0]);
printf("teststr: %s",splitStrings[0]);
}
Others have answered how to fix the error, so I won't go over that. Instead, I will answer the question of why you are getting a segmentation fault.
So, let's step through your code and see what's happening!
const int buffsize = 32;
char* splitStrings[buffsize];
Alright! So far, you have declared a const int of size 32 (good use of const btw!), and you have created a pointer to an array of characters of size 32!
So let's look at the next line!
splitStrings[0][0] = 'a';
So now, you are trying to look at the first item in the array that splitStrings points to, and then looking at the first item in that array. And this is where you get your segmentation fault!
In C, a segmentation fault occurs when something tries to access memory that it is not allowed to access. In this case, it's alright for you to access splitStrings[0], but not splitStrings[0][0]. This is because you currently don't have an array at splitStrings[0] - instead, you just have an unassigned pointer to a character.
So, when the compiler tries to work through that, it says "Okay, let's look at the first item in splitStrings! Alright, that's a pointer to a character! Now, let's look at the first item under that character! It's - wait, hold on. I haven't assigned that yet, it isn't allowed to have its own array yet! Segmentation fault!"
To fix this, you will need to create a 2D array (that's an array of arrays) and allocate that memory. EsmaeelE has given good instructions on how to do that in their answer here. I also highly recommend the TutorialsPoint segments on multi-dimensional arrays and arrays of pointers. The site is an excellent resource for anyone trying to learn the C programming language!
I hope that helped you understand the segmentation fault better! Feel free to ask for any clarifications!
How can I write the program below without any functions like strcpy()?
I know that we can do it with functions but I want to know learn how to do it without any function.
#include <stdio.h>
#include <string.h>
struct name
{
char fname[100];
};
struct list
{
struct name m;
};
int main()
{
struct list l;
strcpy(l.m.fname,"hello");
}
With C99 (or newer):
l.m = (struct name){"hello"};
That's a compound literal. See it live on coliru.
Note that it only works if the array is inside a struct, as in your original, because C does not allow direct assignment to an array.
All the same, the strcpy may be slightly faster, because it will only copy six bytes, while the compound literal assignment above copies 100.
I believe it would pretty much require writing out the code behind the function itself. Either that or you could hardcode every value.
You pretty much have to just expand out the code that would be in strcpy, which is just simple loop copying over each character until it hits the null terminator at the end..
{
struct list l;
const char *in = "hello";
char *out = l.m.fname;
while (*in)
*out++ = *in++;
}
*out=0;
}
I just began starting to code in C and having a lot of difficulties with an assignment. I'm suppose to use malloc and free to create a record database using structures. The structures will act as my database. I need to be able to add and delete records. I also cant use arrays for my structures but can use arrays anywhere else in the code. The teacher gave me an idea on how to lay out the code but I don't understand how to save my inputs to add it to a record. Any help??
I have a lot of my code commented out to trouble shoot. also the the two printf statements on the bottom of main are there for troubleshooting. I can get it to print out first name but soon as I add last name, I get a seg fault. I believe I'm not allocating memory for this to happen but don't fully understand this stuff yet.. PLEASE HELP! Thanks!!!!
The problem lies in "library" variable of type "struct record" initialization or actually the lack of it:
struct record library; //this will hold info for user input
fName and lName members are uninitialized pointers to char. Allocate memory for your buffers and initialize those pointers to point to those buffers. Uninitialized pointers simply point to "some" memory location. When you put data into that location anything can happen! Alternatively provide fixed size buffers in place of those pointers like:
struct record {
char fName[100];
char lName[100];
};
That should work as the first step. Next is to use the malloc/free as your assignment says. Revert struct record back to the original format and use malloc to reserve memory for your buffers before passing them to any function or otherwise using them; like so
#define BUFSIZE (100)
library.fName = malloc(BUFSIZE);
library.lName = malloc(BUFSIZE);
After memory reservation you may use them but don't pass more than BUFSIZE number of characters to those buffers.
After you are done with your buffers free the allocated memory:
free(library.fName);
free(library.lName);
After freeing the buffers you may not use them anymore.
Also don't use gets(). It doesn't provide any protection for buffer overflows as the maximum buffer size is not passed as a parameter to gets(). It has been deprecated and will be removed from the forthcoming standard C1X as unsafe.
Because you are reading data into uninitialized pointers:
printf ("Please enter your first name:\n");
gets(library.fName);
printf ("Please enter your last name:\n");
gets(library.lName);
Allocate memory using malloc and use them and free() them once you are done. If you don't need pointers, you can use arrays in your struct.
Please don't gets() as it can't prevent buffer overflow. Use fgets() instead.
int main() should be int main(void) or int main(int argc, char *argv[]) or its equivalent.
None of your struct members have memory allocated to them. For ease, first define them as
char fName[10];
char lName[10];
etc,
Once you are comfortable with this, then try memory allocation. (IOW, one concept at a time)
The problem you have having is that you are not actually allocating any memory to store the input. Let's start with your struct:
struct record{
char * fName;
char * lName;
};
In memory this struct is just two char pointers. The struct itself is 8 bytes long. The pointers aren't initialized to anything, so they have random values. When you use them as pointers, you will point to a random location in memory.
If you want to actually store the first and last names in your struct, then you could create the struct like this:
static const int MaxNameLength = 255;
struct record{
char fName[MaxNameLength + 1];
char lName[MaxNameLength + 1];
};
Alternately you could use the struct the way that you wrote it, but allocate memory for the buffers and update the pointers. If you did that you would need to do this:
static const int MaxNameLength = 255;
struct Record library;
library.fName = (char *)malloc(MaxNameLength + 1);
library.lName = (char *)malloc(MaxNameLength + 1);
Both these methods are valid, but the advantage to the first method is that you would not need to clean up memory yourself. When the struct goes out of scope all the memory is freed. If you malloc the memory yourself, then you also need to free it.
struct record{
char * fName;
char * lName;
//char * sAddress;
//char * city;
//char * state;
//int * zip;
};
In your structure you are using char * fname
but you input method was not correct you have to do malloc for that
But for a newbie in C
keep fname and lname as char array like
struct record{
char fName[100];
char lName[100];
//char * sAddress;
//char * city;
//char * state;
//int * zip;
};
Now your above code works fine ..
fName and lName are pointers, in general you have to allocate memory to each pointers and free memory for each pointer too. If you read or write on a pointer which is unassigned memory segmentation fault will occur,
You can create an array like name[20] and use gets function. Allocate memory to lName and fName like malloc(strlen(name)). Later on free in the end. Try to malloc and free in main function as it can create problem (you will learn later on pass by value and pass by refernce issues)