struct room
{
char venue[15]; //variable
}
*stream;
.
.
.
void idealounge(){
int i,idealounge[10];
char room1[10]="MMLC";
*** ** stream->venue = room1;*****
}
This is a room booking system.
The name of the room called MMLC.
I expect it can store "MMLC" to stream->venue but it shows errors like "incompatible values" etc.
The statement:
char venue[15];
declares venue to be an array of size 15 of char. Then,
char room1[10]="MMLC";
initialises the first 4 bytes of room1 with the string literal "MMLC", setting the rest to \0.
Then,
stream->venue = room1;
is invalid, because venue is an array, not a pointer. Arrays are not modifiable l-values. You can't assign arrays like this.
If you want to copy the contents of room1 to the contents of venue, use standard strcpy().
That being said,
struct room
{
char venue[15]; //variable
}
*stream;
only allocates space for the pointer, which is uninitialized and isn't pointing to anything meaningful. So first allocate memory and initialise the pointer:¹
stream = malloc (sizeof (struct room));
Then check if it succeeded:²
if (!stream) {
perror ("malloc()");
/* handle error here...*/
}
Now perform the string copy.
Alternatively, you can allocate the struct with automatic storage duration, which is simpler and less error-prone:
struct room bedroom;
and then assign it's address to the pointer:
stream = &bedroom;
This avoids the need for dynamic memory allocation, which you might fail to free() later on.
[1] — NB that I do not cast the result of malloc(). malloc() returns a generic void *, or void pointer, which is automatically promoted to the correct type. So there's no need to cast, and doing so might hide a potential bug.
See also: Do I cast the result of malloc?
[2] — POSIX-compliant systems set errno on malloc() failure, the above code snippet assumes it does. But you may not wish to take it for granted, and handle the error in another way.
struct room
{
char venue[15]; //variable
}
*stream = NULL;
void idealounge() {
int i;
int idealounge[10];
char room1[10]="MMLC";
stream = (struct room *)malloc(sizeof(struct room));
strcpy(stream->venue, room1);
}
You should write this way.
Related
It is possible to declare a string of the required size using char name[size], however if I want to use char *name, how will I specify the size that I require using malloc()?
I found out that I cannot use char *name = malloc(5*1); within the structure declaration.
I have tried using
struct data
{
int age;
char *name;
};
On running this code and entering the string I encountered Segmentation fault.
How must I specify the size?
You need to specify the size of the pointer, you need to make the pointer to point to a valid memory, that's all. Moreover, it not necessary to use malloc(). You can either
allocate memory to the pointer via allocator functions, malloc() or family
make the pointer point to the address of any other char variable (or array)
To elaborate, you create a variable var of type struct data, and then, make var->name point to a valid chunk of memory.
That said, to use malloc() for allocating required size of memory, you need to supply the required size as the argument to malloc() (in bytes).
let's say you create a variable a of the type struct data
struct data a;
Now allocate memory to the name member of a i.e,
a.name = malloc(size_of_name + 1); //+1 for '\0' character at the end
Now you can use a.name to store and use the string
Don't forget to free the allocated data before terminating the program. for this use free(a.name).
You need to allocate the memory like:
data* r = malloc(sizeof(data));
r->name= malloc(20);
assuming the name can hold 20 chars
You'd need to supply a way to initialize your structure. For example:
void init_data (struct data *p_data) {
if (p_data)
p_data->name = malloc(STR_LEN);
}
And you should couple that with a function to free the memory:
void release_data (struct data *p_data) {
if (p_data)
free(p_data->name);
}
It would than be called whenever you want to use your structure.
struct data d;
init_data(&d);
/* use d */
release_data(&d);
I have a pointer to several structures that have been allocated memory via:
STRUCTNAME *ptr;
ptr = (STRUCTNAME *)malloc(sizeof(STRUCTNAME)*numberOfStructs);
The structures are accessed via a offset like so:
(ptr + i)->field;
The structures have 2 fields that are character pointers as follows:
typedef struct
{
char *first;
char *second;
}STUCTNAME;
These fields are allocated memory as follows:
(ptr + i)->first = (char *)malloc(strlen(buffer));
This appears to work but when I try to free the pointers within the structures I get a segmentation fault 11 when I do this:
free((prt + i)->first);
Help?
Notes:
buffer is a character array. Offsetting a pointer by a integer should increment the pointer by the size of what it is pointing to times the integer correct?
Here is a link to my full source code. I have not written some of the functions and I am not using the freeAllpointers and printAll yet.
https://drive.google.com/file/d/0B6UPDg-HHAHfdjhUSU95aEVBb0U/edit?usp=sharing
OH! Thanks everyone! Have a happy Thanksgiving! =D (If you're into that kinda stuff)
In case, you don't initialize all those members in that piece of code, you're not showing us:
Allocate the struct storage (STRUCTNAME*) with calloc(), so that all allocated memory, namely firstand second are zero at the beginning. Passing NULL to free() will result in a no-op. Passing any wild (garbage) pointer to free() may cause a segmentation fault.
To detect a double-free, set ptr[i].first = NULL; after free(ptr[i].first); as a defensive measure for testing.
Notes: buffer is a character array. Offsetting a pointer by a integer
should increment the pointer by the size of what it is pointing to
times the integer correct?
Yes, except for void* on those compilers, which don't define sizeof(void), which is defined to have undefined behavior, to a value > 0: What is the size of void?
Edit:
void makeReviews(FILE *input, REVIEW *rPtr, int numReviews) <-- This does NOT return the new value of rPtr. In main(), it will remain NULL.
Do something like this:
REVIEW* makeReviews(FILE *input, int numReviews);
//...
int main(){
//...
rPtr = makeReviews(input,numReviews);
//...
}
or
void makeReviews(FILE** input,REVIEW** rPtrPtr,int numReviews){
REVIEW* rPtr = *rPtrPtr;
//...
*rPtrPtr = rPtr;
}
//...
int main(){
//...
makeReviews(input,&rPtr,numReviews);
//...
}
fgets(cNumReviews, sizeof(cNumReviews), input); <-- Perhaps, you could use something like fscanf().
struct integer* convert_integer(char* stringInt)
{
struct integer* convertedInt_1;
char* stringArray3 = (char *) malloc (sizeof(char));;
free(stringArray3);
stringArray3 = stringInt;
convertedInt_1->digits = atoi(stringArray3);
stringArray4 = stringInt;
}
this is a sample of the code. this code is giving me an error when i use the standard library from c "Warning: assignment makes pointer from integer to without a cast"
so i need to know how to convert a dynamically numerical string into dynimacally struct integer
You do not need any dynamic allocation for char string here, nor do you need an additional char * pointer.
struct integer* convert_integer(char* stringInt)
{
/*Allocate memory to structure,You cannot return pointer to local structure*/
struct integer* convertedInt_1 = (struct integer*)malloc(sizeof(*convertedInt_1));
/*Convert the string to integer*/
int i = atoi(stringInt);
/*Assign converted integer to structure member*/
convertedInt_1->digits = i;
/*return pointer to heap allocated structure*/
return convertedInt_1 ;
}
There are a lot of problems with this code, but I'll try to walk you through them.
One, you malloc only one char worth of memory, not the amount of memory needed to hold your array. You really need to include an argument for the size of the array to be changed if the string is not null terminated.
Second, you're trying to use memory after you free it. This is bad. Very bad. You should only free memory after you're finished with it.
Next, you're trying to atoi the entire array at once. This is going to try to change the entire string into one number, not one int.
What I think you want, is to convert each character from stringInt to a (single digit) int in your result. For this, use a for loop to iterate through the array.
I'm pretty sure you want to be using int and not integer.
Last, you forgot to return anything - this doesn't compile.
I have a structure called string
typedef struct {
char *s;
int len;
} string_t;
typedef struct {
uint32_t numb;
} msg_t;
where in the function
void myfunct()
{
msg_t msg;
memset(&msg, 0, sizeof(msg));
msg.numb = 1;
char *ClientSendBuf[sizeof(msg)];
string_t buffer = {ClientSendBuf[sizeof(msg)],strlen(ClientSendBuf[sizeof(msg)])};
}
Tried to initialize an array (basically a buffer that I need to send later on) using UDP,
but it gives me an error of segmentation fault (on the third line in void myfunct.
So the thing with buffer is that it should be a type of string_t, how can I fix this segmentation fault?
P.S. I forgot to mention, I want to copy the whole structure to the buffer variable (that should be type string_t) using memcopy. So am I doing the wrong thing above? How can I do this?
There are a few things you have to consider in initializing your structure, as it has a pointer member char *s simple assignment will not work. Simple assignment will just copy the pointer address and not the content it is pointing to.
There are a few problems in your assignment code:
1. You declared an array of char * with sizeof(msg) elements, none of which are allocated memory; but your structure need char * and not char *[]
2. You are accessing an array element which is out of bounds (ClientSendBuf[sizeof(msg)]) and also not pointing to any valid address.
You can create a simple char array & copy it to the structure. As you are using a pointer member it is your responsibility to allocate memory and free memory.
Hope the code below can provide you with some references:
void myfunct()
{
msg_t msg;
memset(&msg, 0, sizeof(msg));
msg.numb = 1;
char ClientSendBuf[] = "This is my message";
string_t buffer = {
strdup(ClientSendBuf), /*Can return NULL so add error check*/
strlen(ClientSendBuf)
};
/** Or **/
string_t buffer;
buffer.s = malloc(strlen(ClientSendBuf)+1);
if(NULL == buffer.s)
{
/* Memory allocation failed. Handle error.*/
}
/* Zero fill */
memset(buffer.s, 0, strlen(ClientSendBuf)+1);
strcpy(buffer.s, ClientSendBuf);
buffer.len = strlen(ClientSendBuf);
/*Opeartions with buffer*/
/*Call free in both cases !*/
free(buffer.s);
}
Hope this help!
ClientSendBuf - put some thing in it and also put it on the heap.
The problem is that you don't allocate memory to any element of ClientSendBuf. You should use malloc here to first allocate the memory.
I see two things that are wrong. First, accessing ClientSendBuf[sizeof(msg)] is undefined behavior, because that character is after the end of CliendSendBuf. Then you're assigning a char (namely ClientSendBuf[sizeof(msg)]) when a char * is expected.
And if you want to use buffer outside that function you have to put ClientSendBuf on the heap, because it will be overwritten by other stack frames after you exit (i.e. sort of deleted), so the pointed data will be throwed off.
Now, since you want a copy of the whole ClientSendBuff, you need an array of string_t. Then, you assign every pointer in ClienSendBuff to buffer:
char *ClientSendBuff[sizeof(msg)];
string_t buffer[sizeof(msg)];
int i;
for(i = 0; i < sizeof(msg); i++) {
ClientSendBuff[i] = malloc(100); // you have to initialize (and free when
buffer[i].s = ClientSendBuff[i]; // you don't need them anymore) every pointer
buffer[i].len = 100;
}
But I'm not sure if I got your point. How can a char * [] fit in a char*?
gcc 4.5.1 c89
I have a function that assigns the elements of the following structure:
static struct Config_t {
char protocol[LINE_SIZE];
char mode[LINE_SIZE];
} *app_config = NULL;
The function using malloc and memset to assign and clear the memory.
Once that is done, I have functions that gets the individual elements:
char* get_mode()
{
if(app_config->mode != NULL) {
return app_config->mode;
}
return NULL;
}
Here I am checking that a value has been assigned. And returning NULL if it hasn't. So in the calling function I can check if a NULL is returned. However, if there a better way to do this?
Many thanks for any suggestions,
In C, returning NULL for an error condition is standard practice for functions returning pointers, so you're in good shape there. (For functions that don't return pointers, the usual convention is to return 0 on success and a non-zero error code on error.)
Separately, and perhaps a bit off-topic: mode can't be NULL, though, can it? app_config can certainly be NULL, it's a pointer to a structure, but your mode is defined as an array, an intrinsic part of the struct, not as a pointer. You'll either have the struct, or not, but you won't have only part of the struct. Simply allocating the memory for the struct will allocate the LINE_SIZE chars for mode; in fact, sizeof(struct Config_t) == LINE_SIZE + LINE_SIZE, the structure is an array of characters followed by another array of characters. There are no pointers involved (other than app_config, because you've defined it as a pointer to the structure).
Consequently, to fully allocate your struct Config_t, just do this:
app_config = malloc(sizeof(*app_config));
(or app_config = malloc(sizeof(struct Config_t)); if your platform won't allow the above.) That allocates mode, nothing else required.
If mode were defined as a char *, that would be different:
static struct Config_t {
char *protocol;
char *mode;
} *app_config = NULL;
Now sizeof(struct Config_t) == 2 * sizeof(void*) (see below), the structure itself consists only of two pointers, not any data that they may point to. Allocating the structure does not allocate any storage for them.
#include <stdio.h>
#define LINE_SIZE (200)
struct Config_t {
char protocol[LINE_SIZE];
char mode[LINE_SIZE];
};
struct Config_t_with_pointers {
char *protocol;
char *mode;
};
int main(int argc, char* argv[])
{
printf("sizeof(struct Config_t) = %zu\n", sizeof(struct Config_t));
printf("sizeof(struct Config_t_with_pointers) = %zu\n", sizeof(struct Config_t_with_pointers));
return 0;
}
(Given your compiler, I felt free to use the z format specifier for size_t arguments, as any recent gcc has it [and it's in the C99 standard, Matthew tells us].)
Output (on my 64-bit Linux system):
sizeof(struct Config_t) = 400
sizeof(struct Config_t_with_pointers) = 16
Based on the definition of built in C functions, such as gets(), returning NULL is the ideal way to indicate that it was not possible to make an assignment or allocation.
Well, since the only reason that this happens is one (if no value has been assigned), you don't need more than one value to distinguish between them.
Also, NULL is no valid pointer, so I don't see anything wrong with that.
If you had more possible errors, you could use errno.h for that purpose.