I was wondering why realloc for a char* or whatever 1D array works if I do something like
oldpointer=realloc(oldpointer,newsize);
But when I try with a 2D char* array it fails.
Looking here and there I see that sometimes people use
NewPointer=realloc(oldpointer,newsize) but if it's the only use it will not be useful to me, since I need to resize the matrix' columns and rows often, in a loop (I must fill an array of strings without knowing first how many string I will insert nor the size of each one)
the code I used for trying is this,
void main(){
int max = 5, i,j;
char **matrix;
matrix=malloc(max*sizeof(char));
for(i=0;i<max;i++){
matrix[i]=malloc(max*sizeof(char));
}
matrix=realloc(matrix,max*2*sizeof(char));
strcpy(matrix[4],"we\0");
printf("%s",matrix[4]);
}
Error in `./out': realloc(): invalid next size: 0x00000000015c4010 ***
Aborted
The problem is that your double pointer can't hold pointers because you did not allocate enough space.
matrix = malloc(max * sizeof(char));
/* which is exactly the same as
* matrix = malloc(max);
*/
should be
matrix = malloc(max * sizeof(char *));
/* ^ max pointers, so sizeof a poitner */
then if you want to realloc(), you can do it like this
void *pointer;
pointer = realloc(matrix, 2 * max * sizeof(char *));
if (poitner == NULL)
handleFailure_OrExit_ButDoNot_Use_The_Realloced_Poitner();
matrix = pointer;
Always check the return value of a function if it returns one, for example malloc()/calloc()/realloc() "and any custom implementation normally", return NULL on failure.
First your matrix is an array of char*, so you should be allocating:
matrix=malloc(max * sizeof(char*));
Likewise for the realloc().
You also don't need "we\0", "we" would suffice. All strings in double quotes are NUL terminating string literals. Allocate enough memory for each of char*s and the chars and you should be good.
Related
I have a dynamically-allocated two-dimensional data structure with capacity of 25 strings, each with a length up to 50. How can I grow the last row of t, an array of pointer to arrays, so it has room for a string of length 200 instead of 50? I want it to also preserve the contents of the string.
This is how I have dynamically allocated t, the two-dimensional array structure:
char **t;
t = (char **) malloc (25 * sizeof(char));
for (int i = 0; i < 25; i++)
t[i] = (char *)malloc(50 * sizeof(char));
Can I access the last row with t[24]? How do I actually change the length of the string to 200 instead of 50?
So far, I have tried t[24] = (char *)malloc(200 * sizeof(char)); but I am not sure if this is correct.
Use realloc() to change the size of an existing allocation. If you use malloc() as you did, you lose the original contents of the array, and also lose the pointer to it so you can't free the memory.
char *temp = realloc(t[24], 200 * sizeof(char));
if (temp) {
t[24] = temp;
}
char **init(int n) {
char **result;
result = malloc(n * sizeof(char));
return result;
}
I need help understanding whether the 3rd line is a bug or not. The call to malloc() will create N contiguous blocks on memory on the heap each big enough to store a single character, and it will return a void ptr (base address of the array). However, result is a pointer to a pointer, so it would need to store the address of another pointer which is not the case here?
Maybe you are looking to do something like this:
char *init(unsigned int n) {
char *result;
/* allocate the memory */
result = malloc(n * sizeof(char));
return result;
}
this will allocate memory to store n contiguous characters.
you could reduce the code to:
char *init(int n) {
return malloc(n * sizeof(char));
}
or instead of calling this function you could just directly do:
malloc(n * sizeof(char));
or you could create a macro
#define INIT_CHAR_ARR(n) malloc((n) * sizeof(char))
if you want n contiguous character pointers:
malloc(n * sizeof(char*))
It would help us help you if you explained your end goal, maybe there is a better way to do what you are doing.
I am trying to reduce the size of a char ** double pointer using realloc.
First the char ** pointer is allocated using malloc and then the individual char* pointers as given below.
char **first= (char**)malloc(num*sizeof(char*));
char **last=(char**)malloc(num*sizeof(char*));
for(int i=0;i<num;i++)
{
//each individual pointer holds 20 characters
first[i]=(char*)malloc(20*sizeof(char));
last[i]=(char*)malloc(20*sizeof(char));
}
Now after some operations, I want to reduce the size of first and last by one counter value where counter is less than num.
Purpose is to free last counter number of records.
If I do the following
//Freeing up internal pointer memories
i = 0;
while (i<counter)
{
free(first[num1-1 - i]);
free(last[num1-1-i]);
i++;
}
//Reducing the size of the double pointer using realloc
first = (char **)realloc(first, (num1-counter) * sizeof(char *));
last = (char **)realloc(last, (num1-counter) * sizeof(char *) );
After this if I print the records
for(i=0; i<num - counter; i++){
printf("First Name: %s ",first[i]);
printf("Last Name: %s ",last[i]);
}`
The last record seems to be corrupted.
If I just perform the following and do not free the individual char * pointers, it works fine.
first = (char **)realloc(first, (num1-counter) * sizeof(char *));
last = (char **)realloc(last, (num1-counter) * sizeof(char *) );
My question is does realloc of a double pointer to reduce the size, internally frees up the internal pointers and as I am doing both, it is some how corrupting the memory?
To answer your question: No, it doesn't.
Freeing the nested pointers in a char ** might be rude if the pointer is still in use somewhere else.
The C compiler doesn't follow memory pointers around, nor does it count object references, so it's up to you to free (or keep) the allocated memory of the nested strings within the char **.
As for the example code itself, it seems to have issues, but these were described in the comments to your question.
I have to maintain an array of strings, which each string will contain the IP address of a neighbor. For some reason i need to maintain them as strings.
typedef struct _neighbors
{
int num_neigbors;
char **neighbor_address;
} neighbors;
Assume i have two neighbors to add.
I view char ** neighbor_address as an array of char * pointers.
I understand that i need to malloc memory for neighbor_address[0] and neighbor_address[1] to store their IP addresses. Since the IP address is of form "x.y.z.w" i will be doing a malloc of 7*sizeof (char).
My doubt is how much memory should i allocate for the base char **neighbor_address. Should it be 4 bytes so that it can store the IP address of the base pointer of neighbor_address[0]?
I say this because i get a SIGSEGV (Segmentation fault) if i don't do a malloc as follows:
neighbor_address = malloc (1, sizeof (char *));
Anything that i am missing?
You should not do malloc like this-
neighbor_address = malloc (1, sizeof (char *));
you are not following the syntax of malloc here. It is the syntax of calloc. If you are using calloc you can use this method-
neighbor_address = calloc (n, sizeof (char *));
If you want to use malloc Try the following changes-
neighbor_address = (char **)malloc (n * sizeof (char *));
for(i=0;i<n;i++)
neighbor_address[i] = (char *)malloc (8 * sizeof (char));
But You are using structure here. So you need to use arrow operator to allocate memory for char **neighbor_address; because it is a pointer type. Try this-
neighbors -> neighbor_address = (char **)malloc (n * sizeof (char *)); // n -> no of ip addresses
for(i=0;i<n;i++)
neighbors -> neighbor_address[i] = (char *)malloc (8 * sizeof (char));
Oh, I think you didn't understand the max length of an IP Address.
It could be 3 digits between every dot so it can be 255.255.255.255 at maximum.
So the code to dynamically allocate memory for it would be so:
#define MAX_IP strlen("255.255.255.255")
int i;
neighbors my_neighbors;
my_neighbors.num_neighbors = ?; //Some value that is the num of IP Addresses needed to be stored.
my_neighbors.neighbor_address = malloc(sizeof(char*)*my_neighbors.num_neighbors); //allocate a char* (that is about to be a string) for each neighbor.
for(i = 0 ; i < my_neighbors.num_neighbors ; i++)
{
my_neighbors.neighbor_address[i] = malloc(sizeof(char)*(MAX_IP+1)); //Allocating enough room in each IP string for 255.255.255.255 + '\0' (null).
}
//Doing some stuff.
//Freeing memory:
for(i = 0 ; i < my_neighbors.num_neighbors ; i++)
{
free(my_neighbors.neighbor_address[i]);
}
free(my_neighbors.neighbor_address);
And that's it.
Hope you understood.
You can allocate the memory like this.
neighbor_address = (char**)malloc(num_neighbors * sizeof(char*));
for(i=0; i<num_neighbors; ++i) {
neighbor_address[i] = (char*)malloc(len_of_address);
}
Make sure that 'len_of_address' is large enough to store all characters (including the terminating '\0' character if you plan to store \0-terminated strings).
Be aware of the fact that you need more space than 1 character per fragment of the ip address if it is a number larger than 9.
So to store 196.168.0.3 you would need at least 12 characters.
First, two things: sizeof(char) is 1, regardless of the implementation. And I think you misunderstood malloc prototype. It takes the number of bytes you want to allocate, and it returns the allocated pointer.
If you want to store x IPs, then you'll have to do:
neighbor_address = malloc(x * sizeof(char*));
And then if you want to store 7 chars in each string, you'll have to do:
for (i = 0; i < x; i++)
neighbor_adress[i] = malloc(7 + 1); // 7 chars plus '\0' character
You must allocate memory for an array of num_neighbors char pointers. But most of all, remember to # include <stdlib.h> : you called malloc with wrong parameters, and that's probably what caused the segfault before a wrong size.
The least error-prone pattern for using malloc is this one :
neighbor_address = malloc(num_neighbors * sizeof *neighbor_address);
Just put the same variable as left operand of = and operand of sizeof, and adjust the number of elements.
I am coding a program which takes a text file as an input, makes the index of the words of it and prints the output(the index) in a file and in the screen.
the input file may be huge. but we KNOW that the maximum variety of the words used in the text file is 200. we don't know what's the maximum of lines and characters of each word. so I should reserve a large number for them. I took the maximum of line 1000 and the maximum characters of each word 100.
I am programming in Turbo C and (I am forced to use that). the compiler allocates just 64kb memory (with the size of the compiler included) and so I have to use MALLOC.
my program is supposed to work in this algorithm:
it reads the input file line by line with fgets. then in the current line, it reads word by word with strtok. so far I have the xth word in yth line. I want to put the words in an array of pointers. so I need a char * word[200]. and I want to show how many times, which word is repeated in which line. so I need a int index [200][1000]. if in yth line, the xth word is existed I would do index[x][y]++.
so now I need to allocate MALLOC memory to these char * word[200] and int index[200][1000] . Can anyone help? I tried all the answers to these question and none of them helped.
You don't quite have malloc right. Your malloc(100) is only allocating 100 bytes. You need
char * words[i] = malloc(sizeof(char *) * 100);
This allocates 800 bytes (100 elements of 8 bytes (size of a pointer) each).
Similarly, in the second malloc, you want two integers, you need
int index[i][j] = malloc(sizeof(int *) * 2);
You shouldn't cast to a pointer; it returns a void pointer, which is implicitly cast to whatever type of pointer you need just by virtue of the assignment.
http://www.cplusplus.com/reference/cstdlib/malloc/
FURTHERMORE:
Additionally, you're trying to stuff 2 bytes into an integer pointer or 4 bytes (100-96 = 4; the 96 is 8 * 12) into a character pointer. I have no idea in the world what that will do. The BEST you can hope for is that you'll just lose the memory somewhere and effectively have 12 character pointers and 2 memory leaks.
If I understand you
In the first loop, I want to define an array of 200 pointers that each pointer, points to an array of char blocks. I want each pointer, points to an array of maximum 100 bytes. Meaning 100 char blocks
char **words = NULL;
int i;
words = malloc(sizeof(char*) * 200);
for(i = 0; i < 200; i++) {
words[i] = malloc(100);
}
There's allocating 200 words with 100 bytes size here.
In the second loop, I want to define a 2D array of int blocks that each block is maximum 2 bytes. meaning 200 * 1000 int blocks.
int **index = NULL;
int i;
index = malloc(sizeof(int*) * 200)
for (i = 0; i < 200; i++) {
index[i] = malloc(sizeof(int) * 1000);
}
Here you allocate 200x1000 int array.
char * words = malloc(200*100);
int * index = malloc(200*1000*sizeof(int));
// word[i*200+j] : character j in word i
// index[i*200+j] : int at index i,j
alternatives:
// mallocing an array for storing a maximum of 200 malloced words
char ** words = malloc(200*sizeof(char*));
// adding a new word, at index i, which is pointed to by pszNewWord (null terminated)
words[i] = strdup(pszNewWord);