On Mon, 28 May 2007 22:32:34 +0200, Piotrek <no*****@noreply.com>
wrote:
>Hi,
I have no idea why my reallocation function (myadd) is breaking up my
array. I'm trying to solve it and it took me few hours already. Maybe
you can look at my code and explain me what is wrong. (I still have
problems with pointers).
Your code has numerous errors and invokes undefined behavior.
>I left my code as it is.
Thank you!
#include "stdafx.h" /* contains stdio.h */
#include <stdlib.h>
#include <string.h>
void *alloca(int n);
char *readr(void);
void myadd(char **A);
void myfree(void *A);
/* Main program */
int main(void){
/* Dynamically allocated array of pointers :*/
char **names;
int i,n=2;
names=(char **)alloca(n);
You need to check that alloca succeeded.
for(i=0;i<n;i++){
names[i]=readr();
You need to check that readr succeeded.
printf("txt: %s\n", names[i]);
}
myadd(names);
myfree(names);
return 0;
}
/* Functions */
void myfree(void *AA){ /* Free all allocated memory */
int i;
void **A=(void **)AA;
for(i=0; A[i]; i++) /* Finish freeing when A[i]=NULL */
free(A[i]);
free(AA);
}
void *alloca(int n){
void **A;
/* Avoid n==0:*/
if(n==0) n=1;
if((A=(void **)calloc(n+1, sizeof(*A)))==NULL) return NULL;
This is a problem waiting to happen. You are allocating space for n+1
objects of type void*. In this instance, you will use the space to
store values of type char*. The standard guarantees that void* and
char* have the same size (and representation). However, if you ever
use this function to allocate space for different types of pointers,
you have no idea if you will allocate enough space. It is entirely
possible for sizeof (int*) to be greater than sizeof (void*).
Why are you using calloc? Do you think initializing a pointer to all
bits 0 has some benefit?
A[n]=NULL;
return A;
}
char *readr(void){
char *buf;
int i;
char c,BB[256]={'\0'};
fflush(stdin);
This invokes undefined behavior. fflush is defined only for output
streams.
>/* Read 255 characters max. Last char is '\0': */
for(i=0; ((c=getchar())!='\n')&&i<255; i++)
getchar returns an int. c is a char. It is possible for getchar to
return a value that will not fit in a char. If so, this would invoke
undesirable (either undefined or implementation defined) behavior.
BB[i]=c;
fflush(stdin);
/* i+1: enable myfree() to free all memory: */
if((buf=(char *)calloc(i+1,sizeof(char)))==NULL){
printf("Oops, can't allocate mem.!\n");
}
else{
strcpy(buf,BB);
return buf;
}
If calloc failed, you do not return anything. This will invoke
undefined behavior. Did you compiler not complain about reaching the
end of the function without returning a value?
>}
/* Should reallocate "names" and add one more entry to it :*/
void myadd(char **A){
int n;
This is an automatic variable that is not initialized. Therefore its
value is indeterminate.
>/* Count rows of array :*/
for(n=0;A[n];n++);
Any attempt to evaluate the indeterminate value in n invokes undefined
behavior.
>/* It is supposed to reallocate "names" but it seems to break it */
if((A=(char **)realloc(A, (n+2)*sizeof(*A)))==NULL)
n contains garbage. It could be negative. n+2 has no meaning.
printf("Oops, can't reallocate mem.!\n");
A[n]=readr();
When realloc fails, you print the error message but then procede to
use A as if it contained a valid pointer. This also invokes undefined
behavior.
A[n+1]=NULL;
Since C passes by value, when you return from this function, the value
of A is discarded. The value of names in the calling function is
unchanged. If the realloc succeeded and allocated a new block of
memory (instead or reusing the existing block), that value will no
longer point to the allocated area. In fact, that value becomes
indeterminate and any use of it in the calling function invokes
undefined behavior.
>}
Remove del for email