*** glibc detected *** realloc(): invalid old size 3 - c

This code sometimes give me a Segmentation fault, why could this be?
void concatenarAlBuffer(char **destino, char caracter)
{
char matrizAux[1];
matrizAux[0]=caracter;
matrizAux[1]='\0';
(*destino) = realloc((*destino),2+(strlen((*destino))*sizeof(char)));
if ((*destino)==NULL)
{
perror("Error al reservar memoria\n");
exit(-1);
}
strcat((*destino),matrizAux);
}

matrizAux can only hold one character. You can't access matrizAux[1] - it's out of bounds.
Declare matrizAux like this:
char matrizAux[2];
Remember that an n-elements array can be indexed in positions 0 up to (and including) n-1.
Also, you don't need sizeof(char), because it it always 1. And parentheses around *destino are useless in this case and make the code harder to read unnecessarily. Here's how I would change your code:
void concatenarAlBuffer(char **destino, char caracter) {
char matrizAux[2];
matrizAux[0]=caracter;
matrizAux[1]='\0';
*destino = realloc(*destino,2+strlen(*destino));
if (*destino == NULL) {
perror("Error al reservar memoria\n");
exit(-1);
}
strcat(*destino, matrizAux);
}

You make
char matrizAux[1];
a 1-char long array.
And then you write to its' second element with
matrizAux[1]='\0';
This might or might not crash depending on what's behind your array in memory.
But it still looks like something's missing.
realloc can reallocate only something that was previously malloc- or calloc-ated.
Trying to reallocate something that doesn't fulfill this condition gives you your error. And that's probably the true case here.

char matrizAux[1] hold only one character. Since you are accessing matrizAux[1], i.e. something out-of-bounds, you are corrupting the memory. This can result in the internal data of the runtime getting corrupted, which results in the segfault during the realloc(), even though the realloc itself is correct.

Related

managing memory in a for loop

I am trying to save information from a file to structs in the heap.
The problem is: if i print out the information in the for loop where i save the data, it works well, but when i print out the data outside that for loop i get only garbage
i wanna know why :( probably i am doing a bad work with the malloc
i could work inside the first for loop but i want to know what i am doing wrong
typedef struct{
int tipoDeCodificacion;
void* carta;
}pedido;
typedef struct{
void* nombre;
void* regalo;
}regalos;
void creacionRegalos(FILE *cartas){
FILE *final=fopen("regalos.txt","w");
int cantidadCartas, i;
fscanf(cartas,"%d\n",&cantidadCartas);
printf("%d\n",cantidadCartas);
pedido *Pedidos=(pedido *)malloc(sizeof(cantidadCartas));
regalos **Regalos=malloc(sizeof(regalos *)*cantidadCartas);
for(i=0;i<cantidadCartas;i++){
char *lineaCodificada=malloc(sizeof(char)*100);
int *tipo=malloc(sizeof(int));
fscanf(cartas,"%d\n",tipo);
Pedidos[i].tipoDeCodificacion=*tipo;
printf("%d\n",Pedidos[i].tipoDeCodificacion); //this print works well
fgets(lineaCodificada,100,cartas);
Pedidos[i].carta=lineaCodificada;
puts(Pedidos[i].carta); //this print works well
}
for (i = 0; i < cantidadCartas; i++) {
printf("%d\n",Pedidos[i].tipoDeCodificacion); //just prints garbage
printf("%s\n",(char *)Pedidos[i].carta);//prints garbage
}
}
The line:
pedido *Pedidos=(pedido *)malloc(sizeof(cantidadCartas));
is invalid. You are allocating memory for sizeof(int) bytes. You should:
pedido *Pedidos=(pedido *)malloc(sizeof(*Pedidos) * cantidadCartas);
allocate memory for contidadCartas count of pedido structures. The time you access Pedidos memory using pedido* pointer you do undefined behavior.
Your code is really hard to read, badly indented, with strange locale names, no error checking and it leaks memory for all malloc you call. A good code would check all error places if (Pedidos == NULL) { handle_error(); } and if(fscanf("%d", ....) != 1) etc. The allocation of int *typo = malloc(sizeof(int)); straight up leaks memory - it is nowhere freed. I also strongly encourage you to write all code, including all structure, variables and function names in english.

Dynamic Struct with Dynamic Matrix

I'm having a little trouble doing a school project, and I can't post all my code here because it might be copied by my schoolmates.
I have created a Dynamic Struct called Messages with the variable inside it char ** phrases, int lines (number of phrases at the moment), int heaplines(max number of lines my char ** phrases can hold).
My program should work this way: it asks the user to insert messages, allocating memory to them and increasing the variable lines, which is the number of messages he has at the moment, if it reaches the max then I do an reallocation of +10 plus lines and it increases the heaplines. But my true problem is I cant allocate memory to the string the user has inserted because it gives me an error saying:
Incompatible Pointers types "char **" and "char *"
.
MSG->phrases=(char*)malloc((tamphrase+1)*sizeof(char));
Allocating the lines for the matrix of char ** msg it works perfectly, but when I try to allocate memory for the string that is going to be inserted it gives me that error on that line of code above.
Btw, how can I increment the lines of the matrix of phrases?
For example:
MSG->(phrases+i)=(char*)malloc((tamphrase+1)*sizeof(char));
(I know this is wrong, but I hope you guys know what I'm trying to say)
MSG->phrases=(char*)malloc((tamphrase+1)*sizeof(char)); is a char** so allocating memory to it would be
MSG->phrases=malloc((tamphrase+1)*sizeof(char*));
Well then for each of the tamphrase you allocate memory for holding characters.
MSG->phrases[i]=malloc((MAXLENOFLINE+1)*sizeof(char));
Also you should read about realloc to get an idea about the reallocating when you run out of already allocated memory in your code.
Don't cast the return value of malloc, it's unnecessary and doing so may suppress error in case error occurs.
If you understand the logic of pointers a bit then you wouldn't have problem writing these lines.
you said phrases are char**. Now think what a char** holds. It holds the address of char* variables. Now you will allocate a chunk of memory each capable of holding char* variables and then you return the starting address of it to phrases.
Now same way you think the other way, char* holds the address of a char variable. You will allocate a memory where you will store the char variables. You return the starting address to the char* variables.
phrases[i] holds that.
Without going into detail, the general structure of the code will be something like this
MSG->phrases=malloc((tamphrase+1)*sizeof(char*));
if( MSG->phrases == NULL ){
fprintf(stderr,"Error in malloc");
exit(1);
}
for(size_t i = 0; i < tamphrase+1; i++ ){
MSG->phrases[i]=malloc((MAX_LINE_LENGTH+1)*sizeof(char));
if( MSG->phrases[i] == NULL ){
fprintf(stderr,"Error in malloc");
exit(1);
}
}
...
...
// do cool stuff
..
..
//free the allocated memory
for(size_t i = 0; i < tamphrase+1; i++ ){
free(MSG->phrases[i]);
}
free(MSG->phrases);

What steps do I need to take before I can malloc some other amount of memory in the SAME variable name I have used in a loop?

In a loop, I malloc a certain amount of memory, use it to store some string.
When the loop occurs, I will have to malloc another amount of memory, to the same
variable I have used. The amount of memory depends on user's input. Code goes like
following, (I have simplified it)
int thisMany;
char *message = NULL;
while (1)
{
printf("How many characters will you type?");
scanf("%d\n", thisMany);
message = malloc(sizeof(char*)*(thisMany+1));
message[thisMany+1] = '\0';
for (;thisMany > 0; thismany--)
{
message[thisMany] = a;
}
printf("%s", message);
/* this is the stage where I don't know what to do with 'message'
in order for the code to work after the loop */
}
I have tried using 'free(message)' and some other stuff. Please let me know if you know something that would make this work.
while (1)
{
printf("How many characters will you type?");
scanf("%d\n", thisMany);
Your allocation here is not correct: you want to allocate a char pointer, of a given number of characters. So it should be:
message = (char *)malloc(sizeof(char)*(thisMany+1));
// Always verify *allocs. They're mischievous at best, and often evil.
if (NULL == message) {
fprintf(stderr, "Out of memory!\n");
exit(-1);
}
There was no harm done, however, since sizeof(char *) is four or eight times larger than sizeof(char), so you were allocating more memory than necessary. But now this line of code becomes dangerous:
message[thisMany+1] = '\0';
You have allocated thisMany+1 characters, numbered from 0 to thisMany. So the thisMany+1-th character falls outside allocated memory; what is called an "off-by-one" buffer overflow. It should be:
// One less than the number given to malloc()
message[thisMany] = '\0';
Finally:
/* this is the stage where I don't know what to do with 'message'
in order for the code to work after the loop */
What you need to do is to free the memory you allocated.
free(message); message = NULL;
The reassignment of message to NULL is not strictly necessary but I find it very useful; after being freed, message still points to an area of allocated memory, which still has the same content. So you could do
free(message);
printf("%s\n", message);
and sometimes, maybe often, it would actually work, hiding a potentially disastrous bug.
Setting message to NULL guarantees this will not happen, and improves the chances that any improper usage will be conspicuous enough to be caught at once. And it makes behaviour deterministic in this respect, which is much better for catching bugs.
An alternative, as already pointed out, is to set message to NULL before the loop, and then use realloc instead of malloc. realloc() will behave just like malloc when passed a NULL argument:
message = NULL;
for (;;) {
// Loop
message = realloc(...);
if (NULL == message) {
...
}
}
// finally free message outside the loop.
// Checking that it is *not* NULL, in case the check above did not exit
// but just, say, printed an error message and exited the loop via break
if (message != NULL) {
free(message); message = NULL;
}
After you have finished with the message (after printf), you should free (message) to free it up.
Alternatively you can realloc it rather than malloc-ing it.

Can someone find the mistake? Pure C realloc

I've got this code:
int main() {
int i=0, n=0;
char sep=NULL;
double **aero=(double**)malloc(sizeof(double*));
*aero=(double*)malloc(2*sizeof(double));
printf("Zadejte souradnice:\n");
while (1) {
aero=(double**)realloc(aero,(n+1)*sizeof(double*));
for (i=0; i<n+1; i++) {
aero[i]=(double*)realloc(aero[i],2*sizeof(double));
}
if ((scanf("[%lf,%lf]%c",&aero[n][0],&aero[n][1],&sep))==3 && (sep=='\n' || sep==' ')) {
n++;
continue;
} else if (!feof(stdin)) {
printf("Nespravny vstup.\n");
freeArray2D(aero,n);
return 0;
}
break;
}
}
It works fine, but I can scanf coordinates (in format: [x,y]) only 19 times. Then it shows me Segmentation fault (core dumped). I use Linux compiler gcc -Wall -pedantic main.c -lm I have no idea, where is the problem. Thanks for any help.
You never assign a fresh malloced buffer to aero[1], but pass the garbage in there to realloc. Maybe you expected the realloc for aero to zero-initalize the memory?
In aero[i]=(double*)realloc(aero[i],2*sizeof(double)), if i == n, then aero[i] is uninitialzed. You should not call realloc on an uninitialized pointer.
Your specific problem is that you realloc a pointer, aero[n], that was never malloced in the first place (and is not necessarily NULL). That's a recipe for disaster.
You also have another issue though it's more an unnecessary-work problem than a fatal flaw. You are re-allocating every single aero[] variable in the loop when they're not actually changing in content or size. It appears to me that all you need to do in the loop is simply increase the size of the first level of memory aero and allocate memory for its new element:
while (1) {
aero = realloc (aero, (n+1) * sizeof (double*));
aero[n] = malloc (2 * sizeof (double));
:
You'll notice I've removed the casting of the malloc return values. This casting is ill-advised in C as it can hide certain subtle errors. C is perfectly capable of converting the void* return values into any other pointer type implicitly.
And, of course, you should never assume that your memory allocations will work - I'd be checking the return values for NULL and exiting immediately if I found one.
The only other issue I had (other than my inability to read Czech of course) was the setting of the char sep to NULL. NULL is usually reserved for pointers rather than characters so it looks more sensible if you initialise it to \0.

How to allocate memory for an array of strings of unknown length in C

I have an array, say, text, that contains strings read in by another function. The length of the strings is unknown and the amount of them is unknown as well. How should I try to allocate memory to an array of strings (and not to the strings themselves, which already exist as separate arrays)?
What I have set up right now seems to read the strings just fine, and seems to do the post-processing I want done correctly (I tried this with a static array). However, when I try to printf the elements of text, I get a segmentation fault. To be more precise, I get a segmentation fault when I try to print out specific elements of text, such as text[3] or text[5]. I assume this means that I'm allocating memory to text incorrectly and all the strings read are not saved to text correctly?
So far I've tried different approaches, such as allocating a set amount of some size_t=k , k*sizeof(char) at first, and then reallocating more memory (with realloc k*sizeof(char)) if cnt == (k-2), where cnt is the index of **text.
I tried to search for this, but the only similar problem I found was with a set amount of strings of unknown length.
I'd like to figure out as much as I can on my own, and didn't post the actual code because of that. However, if none of this makes any sense, I'll post it.
EDIT: Here's the code
int main(void){
char **text;
size_t k=100;
size_t cnt=1;
int ch;
size_t lng;
text=malloc(k*sizeof(char));
printf("Input:\n");
while(1) {
ch = getchar();
if (ch == EOF) {
text[cnt++]='\0';
break;
}
if (cnt == k - 2) {
k *= 2;
text = realloc(text, (k * sizeof(char))); /* I guess at least this is incorrect?*/
}
text[cnt]=readInput(ch); /* read(ch) just reads the line*/
lng=strlen(text[cnt]);
printf("%d,%d\n",lng,cnt);
cnt++;
}
text=realloc(text,cnt*sizeof(char));
print(text); /*prints all the lines*/
return 0;
}
The short answer is you can't directly allocate the memory unless you know how much to allocate.
However, there are various ways of determining how much you need to allocate.
There are two aspects to this. One is knowing how many strings you need to handle. There must be some defined way of knowing; either you're given a count, or there some specific pointer value (usually NULL) that tells you when you've reached the end.
To allocate the array of pointers to pointers, it is probably simplest to count the number of necessary pointers, and then allocate the space. Assuming a null terminated list:
size_t i;
for (i = 0; list[i] != NULL; i++)
;
char **space = malloc(i * sizeof(*space));
...error check allocation...
For each string, you can use strdup(); you assume that the strings are well-formed and hence null terminated. Or you can write your own analogue of strdup().
for (i = 0; list[i] != NULL; i++)
{
space[i] = strdup(list[i]);
...error check allocation...
}
An alternative approach scans the list of pointers once, but uses malloc() and realloc() multiple times. This is probably slower overall.
If you can't reliably tell when the list of strings ends or when the strings themselves end, you are hosed. Completely and utterly hosed.
C don't have strings. It just has pointers to (conventionally null-terminated) sequence of characters, and call them strings.
So just allocate first an array of pointers:
size_t nbelem= 10; /// number of elements
char **arr = calloc(nbelem, sizeof(char*));
You really want calloc because you really want that array to be cleared, so each pointer there is NULL. Of course, you test that calloc succeeded:
if (!arr) perror("calloc failed"), exit(EXIT_FAILURE);
At last, you fill some of the elements of the array:
arr[0] = "hello";
arr[1] = strdup("world");
(Don't forget to free the result of strdup and the result of calloc).
You could grow your array with realloc (but I don't advise doing that, because when realloc fails you could have lost your data). You could simply grow it by allocating a bigger copy, copy it inside, and redefine the pointer, e.g.
{ size_t newnbelem = 3*nbelem/2+10;
char**oldarr = arr;
char**newarr = calloc(newnbelem, sizeof(char*));
if (!newarr) perror("bigger calloc"), exit(EXIT_FAILURE);
memcpy (newarr, oldarr, sizeof(char*)*nbelem);
free (oldarr);
arr = newarr;
}
Don't forget to compile with gcc -Wall -g on Linux (improve your code till no warnings are given), and learn how to use the gdb debugger and the valgrind memory leak detector.
In c you can not allocate an array of string directly. You should stick with pointer to char array to use it as array of string. So use
char* strarr[length];
And to mentain the array of characters
You may take the approach somewhat like this:
Allocate a block of memory through a call to malloc()
Keep track of the size of input
When ever you need a increament in buffer size call realloc(ptr,size)

Resources