I have this struct:
typedef struct
{
char name[3];
int month_num;
int day_num;
int day_size; // amount of days that are field in with tasks.
char *task[40];
}
month; // each month contains a name, its num in the calendar and days.
and I need to assign memory allocation for it.
I was able to assign the memory for the struct itself:
mon = (month*)malloc(12 * sizeof(month));
But I am having trouble to do it the same for the char *task[40].
I tried a lot of possibilities, but non of them worked...
char temptask[40];
mon->task=malloc(strlen(temptask)+1);
for(i=0;i<40;i++)
{
/* Allocating memory to each pointers and later you write to this location */
mon->task[i] = malloc(size);/* If you have a initialized string then size = strlen(tempTask) + 1 */
}
What you have is array of pointers and just access them and allocate memory to each of the pointers individually as shown above.
char *task[40]; is an array of 40 pointers. You probably want a single array of 40 characters, in which case no need to malloc it separately, or else a single pointer in which case you can malloc(40). You can't call strlen() on an uninitialized C string, that's undefined behavior (buffer overrun).
I think, what you need is
char *task;
and then allocate memory as
mon[j].task=malloc(sizeof(temptask));
Next, as you've allocated memory to mon as
mon = malloc(12 * sizeof(month));
the access should be made as
mon[j].task // j being the index, running from 0 to 11
Otherwise, if you really have a char *task[40];, that means, an array of 40 char *s, then you have to allocate memory for each of them, one by one.
int p = strlen(temptask);
for(i=0;i<40;i++)
{
mon[j].task[i] = malloc(p+1);
}
Related
hey I am trying to create a program in which I am trying store elements from one array to another with the use of a pointer to pointer but the problem is that is caused undefined behavior I believe that the problem is that I do not pass the elements in members with a proper way
I know it is a vague way of doing this but It is in only for practising reasons
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct student{
char *name;
int *number;
}T;
int main(void) {
char array[10][100]={"araaaa","bbgt","gffkghgh"};
T arr[10][100];
T *p;
T **p1;
p=&arr[0][0];
p1=&p;
int i=0;
for(i = 0 ; i < 3 ; i++)
{ p=arr[i];
strcpy((*p1)->name,array[i]);
}
/*******print_elements*************/
for(i = 0 ; i < 3 ; i++)
{ p=arr[i];
printf("\n the elements are %s",(*p1)-> name);
}
return 0;
}
When you do this:
strcpy ((*p1)->name, array[i]);
(*p1)->name is an uninitialised pointer. What happens, therefore, is in the lap of the gods.
The easiest fix is to modify your student structure such that name is a buffer, rather than a pointer. At the same time, change number to an int, rather than a pointer to an int::
typedef struct student{
char name [100];
int number;
} T;
If you want to keep name as a pointer then you have to allocate some memory before you store your string in it. This should work:
(*p1)->name = strdup (array[i]);
Don't forget to free the memory when done.
T is made of of two pointers, this first one points to a string of characters in memory.
arr is a 2D array that is allocated to store a total of 1000 T structures.
arr[i] would reference a 1D array of T structures within arr
*p1 would essentially be arr[i], since dereferencing p1 gives you p, which was just set to arr[i]. So, that is not a pointer to a T structure, but to an array of T structures. Forcing the cast will likely give you a reference to the first T structure in that row, however.
->name This value is never set. You allocated an array, but "name" is a pointer to memory, not an array of characters, so '->name' is undefined.
I think you need to change arr to be a single dimension array. You aren't using 90% of it.
And, you need to initialize every T struct in that array. You can use malloc or strdup, and then remember to free them all. Or, set the struct to use an array instead.
I've been banging my head against the wall on this for a couple hours now.
I have a struct defined as follows:
typedef struct historyNode {
int pos;
char cmd[MAXLINE];
char* args[(MAXLINE / 2) + 1];
struct historyNode* next;
} historyNode_t;
I am attempting to copy a passed-in array of strings into the args field within the above struct. This happens in the method below:
void addToHistory(history_t* history, char* args[(MAXLINE / 2) + 1]) {
historyNode_t* node = malloc(sizeof(historyNode_t));
...
int index = 0;
while (args[index] != NULL) {
node->args[index] = args[index];
...
When I attempt to access this node's args value at a later time outside of the method, it spits out a value equal to whatever is in the passed-in args array at that moment; ie, the values aren't actually being copied, but rather the addresses are.
I feel like this is simple but it is frustrating me. Any tips on how this can be remedied are super appreciated.
I attempt to access this node's args value at a later time outside of the method
For doing that you should've returned pointer to struct historyNode wherever you are trying to access the args value. Here is an example for that:
#include<stdio.h>
#include<stdlib.h>
struct node
{
char *a[2];
};
struct node *fun()
{
char *c[]={"hello","World"};
struct node *ptr= malloc(sizeof(struct node));
ptr->a[0]=c[0];
ptr->a[1]=c[1];
return ptr;
}
int main()
{
struct node *ptr=fun();
printf("%s %s\n",ptr->a[0],ptr->a[1]);
return 0;
}
OUTPUT: hello World
In C, C++,
char charA[10]; // Array of char (i.e., string) up to 9+1 byte
// 10 bytes of memory is reserved
char *string; // Pointer to a null-terminated string
// Memory for 1 pointer (4 or 8 bytes) are reserved
// Need to allocate arbitrary bytes of memory
// Up to programmer to interpret the memory structure
// E.g.,
// As array of pointers to string
// A long string
// etc.
// This pointer could be passed to other functions
// and content at that pointed address could be changed
//char *strings[]; // Cannot declare pointer to unknown length of array
// Use char** as below
char **ptrs2Strings; // Pointer to pointer to char
// Memory for 1 pointer (4 or 8 bytes) are reserved
// Need to allocate arbitrary bytes of memory
// Up to programmer to interpret the memory structure
// E.g.,
// As array of pointers to string
// A long string
// etc.
// The pointer to pointer could be passed to other
// functions. The content at that pointed address is
// only an address to an user-allocated memory.
// These functions could change this second address as
// well as content of the memory pointed by the second
// address.
char *charvar[10]; // array of 10 char pointers
// Memory for 10 pointers (40 or 80 bytes) are reserved
// Programmer could allocate arbitrary bytes of memory
// for each char pointer
char stringA[10][256]; // array of 10 strings, and each string could store
// up to 255+1 bytes
I hope this could help you.
During my project, I am confronted with C program.
As shown below, htmp is a struct pointer. We first allocate a memory for it. But why should we allocate a memory for its element word again?
If it's essential to allocate memory for each element of a struct, why not allocate memory for its other elements, id and next?
#define HASHREC bitewisehash
typedef struct hashrec {
char *word;
long long id;
struct hashrec *next;
} HASHREC;
/* Move-to-front hashing and hash function from Hugh Williams, http://www.seg.rmit.edu.au/code/zwh-ipl/ */
/* Simple bitwise hash function */
unsigned int bitwisehash(char *word, int tsize, unsigned int seed) {
char c;
unsigned int h;
h = seed;
for (; (c =* word) != '\0'; word++) h ^= ((h << 5) + c + (h >> 2));
return((unsigned int)((h&0x7fffffff) % tsize));
}
/* Insert string in hash table, check for duplicates which should be absent */
void hashinsert(HASHREC **ht, char *w, long long id) {
HASHREC *htmp, *hprv;
unsigned int hval = HASHFN(w, TSIZE, SEED);
for (hprv = NULL, htmp = ht[hval]; htmp != NULL && scmp(htmp->word, w) != 0; hprv = htmp, htmp = htmp->next);
if (htmp == NULL) {
htmp = (HASHREC *) malloc(sizeof(HASHREC)); # allocate memory for htmp
htmp->word = (char *) malloc(strlen(w) + 1); # why allocate memory again ?
strcpy(htmp->word, w); #
htmp->id = id; # why not allocate memory for htmp->id ?
htmp->next = NULL; # why nor allocate memory for htmp->next?
if (hprv == NULL) ht[hval] = htmp;
else hprv->next = htmp;
}
else fprintf(stderr, "Error, duplicate entry located: %s.\n",htmp->word);
return;
}
You need to separate in your mind two things (1) in what memory is the thing I want to store stored?; and (2) what variable (pointer) holds the address to where it is stored so I can find it again.
You first declare two pointers to struct hashrec:
HASHREC *htmp, *hprv;
A pointer is nothing but a variable that holds the address to something else as its value. When you first declare the two pointers, they are uninitialized and hold no address. You then, in a rather awkward manner, initialize both pointers within a for loop declaration, e.g. hprv = NULL, htmp = ht[hval] and later hprv = htmp, htmp = htmp->next so presumably both pointers now hold an address and point somewhere.
Following the loop (with an empty body), you test if (htmp == NULL), meaning that htmp does not point to an address (which can be the case if you have found the hash-index of interest empty).
Then in order to provide storage for one HASHREC (e.g. a struct hashrec) you need to allocate storage so you have a block of memory in which to store the thing you want to store. So you allocate a block to hold one struct. (See: Do I cast the result of malloc?)
Now, look at what you have allocated memory for:
typedef struct hashrec {
char *word;
long long id;
struct hashrec *next;
} HASHREC;
You have allocated storage for a struct that contains (1) a char *word; (a pointer to char - 8-bytes (4-bytes on x86)); (2) a long long id; (8-bytes on both) and (3) a pointer to hold the address of the next HASHREC in the sequence.
There is no question that id can hold a long long value, but what about word and next? They are both pointers. What do pointers hold? The address to where the thing they point to can be found. Where can word be found? The thing you want is currently pointed to by w, but there is no guarantee that w will continue to hold the word you want, so you are going to make a copy and store it as part of the HASHREC. So you see:
htmp->word = malloc(strlen(w) + 1); /* useless cast removed */
Now what does malloc return? It returns the address to the beginning of a new block of memory, strlen(w) + 1 bytes long. Since a pointer holds the value of something else as its value, htmp->word now stores the address to the beginning of the new block of memory as its value. So htmp->word "points" to the new block of memory and you can use htmp->word as a reference to refer to that block of memory.
What happens next is important:
strcpy(htmp->word, w); #
htmp->id = id; # why not allocate memory for htmp->id ?
htmp->next = NULL; # why nor allocate memory for htmp->next?
strcpy(htmp->word, w); copies w into that new block of memory. htmp->id = id; assigns the value of id to htmp->id and no allocation is required because when you allocate:
htmp = malloc(sizeof(HASHREC)); /* useless cast removed */
You allocate storage for a (1) char * pointer, (2) a long long id; and (3) a struct hashrec* pointer -- you have already allocated for a long long so htmp->id can store the value of id in the memory for the long long.
htmp->next = NULL; # why nor allocate memory for htmp->next?
What is it that you are attempting to store that would require new allocation for htmp->next? (hint: nothing currently) It will point to the next struct hashrec. Currently it is initialize to NULL so that the next time you iterate to the end of all the struct hashrec next pointers, you know you are at the end when you reach NULL.
Another way to think of it is that the previous struct hashrec next can now point to this node you just allocated. Again no additional allocation is required, the previous node ->next pointer simply points to the next node in sequence, not requiring any specific new memory to be allocated. It is just used as a reference to refer (or point to) the next node in the chain.
There is a lot of information here, but when you go through the thought process of determining (1) in what memory is the thing I want to store stored?; and (2) what variable (pointer) holds the address to where it is stored so I can find it again... -- things start to fall into place. Hope this helps.
When you allocate the memory for the struct, only enough memory to hold a pointer is allocated for the member word, that pointer also has to point to valid memory which you can then allocate.
Without making it point to valid memory, it's value is indeterminate and trying to dereference such pointer with an indeterminate value is undefined behavior.
malloc(size) will allocate memory of given size and returns starting address of the allocated memory. Addresses are stored in pointer variables.
In char *word, variable word is of pointer type and it can only hold a pointer of type char i.e., address of a character data in memory.
so, when you allocate memory to the struct type variable htmp, it will allocate memory as follows, 2 bytes for *word, 4 bytes for id and 2 bytes for *next
Now, lets assume that you want to store following into your struct:
{
word = Elephant
id = 1245
}
Now you can save id directly into id member by doing this htmp->id = 1245. But you also want to save a word "Elephant" in your struct, how to achieve this?
htmp->word = 'Elephant' will cause error because word is a pointer. So, now you allocate memory to store actual string literal Elephant and store the starting address in htmp->word.
Instead of using char *word in your struct, you could have used char word[size] where no need to allocate memory separately for member word. The reason behind not doing so, is that you want to select some random size for word, which can waste memory if you are storing less characters and which even fall shot if word is too big.
I'm currently working on dynamically allocating my array of structures and I'm unsure how to continue. This is my structure:
struct Word_setup
{
char word[M];
int count;
} phrase[N];
I know malloc returns a pointer to a block of memory, but I'm not sure how this works when it comes to an array of structures.
If anyone could please clarify that would be much appreciated!
Probably you meant:
struct Word_setup {
char word[M];
int count;
};
It's a good idea to avoid defining variables in the same line as a struct definition anyway, to help with code readability.
Then you can allocate an array of these:
int main()
{
struct Word_setup *phrase = malloc(N * sizeof *phrase);
// use phrases[x] where 0 <= x < N
phrase = realloc(phrase, (N+5) * sizeof *phrase);
// now can go up to phrases[N+4]
free(phrase);
}
Of course you should check for failure and abort the program if malloc or realloc returns NULL.
If you also want to dynamically allocate each string inside the word then there are a few options; the simplest one to understand is to change char word[M] to char *word; and each time you allocate a phrase, write the_phrase.word = malloc(some_number); . If you allocate an array of words you'll need to loop through doing that for each word.
I suppose that N and M is a compile-time known constants. Then just use sizeof, .e.g.
struct Word_setup*ptr = malloc(sizeof(struct Word_setup)*N);
Maybe you want a flexible array member. Then, it should always be the last member of your struct, e.g.
struct Word_setup {
int count;
unsigned size;
char word[]; // of size+1 dimension
};
Of course it is meaningless to have an array of flexibly sized structures -you need an array of pointers to them.
Im having problems with c and pointers. I keep grinding on this and it has to be easy. I have a struct and I allocate in one function, then pass the pointer back to the original function. But when I try to fill the values of the struct with other variables, and then print them or copy them , the app segfaults saying the memory address is out of bounds.
struct memcache_buffer{
int elements, action;
char keys[MAX_KEYS], values[MAX_KEYS], returns[MAX_KEYS]; //action 0 = delete , 1 = get 2 = set
}memcache_buffer;
struct memcache_buffer* memcache_allocate_buffer(int size){
struct memcache_buffer *buffer;
buffer =malloc(sizeof(struct memcache_buffer));
return buffer;
}
void memcache_set(char * key, char * value){
pthread_t process_t;
struct memcache_buffer *buffer=memcache_allocate_buffer(1);
char keys,values;
buffer->elements = 1;
buffer->action=2;
//printf("crash?\n");
printf("%s %s",key,value);
snprintf(buffer->keys[0],KEY_SIZE,"%s",key);
snprintf(buffer->values[0],VALUE_SIZE,"%s",value);
pthread_create(&process_t,NULL,memcache_process,buffer);
}
am I allocating the memory right? allocating memory and these pointers are sure rough, especially only messing with php in the past.
Here's your problem:
struct memcache_buffer{
char keys[MAX_KEYS], values[MAX_KEYS]
}
snprintf(buffer->keys[0],KEY_SIZE,"%s",key);
^^^
snprintf(buffer->values[0],VALUE_SIZE,"%s",value);
^^^
Drop the [0] or snprintf will try to dereference some bogus value.