Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

C Programming Language

Reallocate an array (pointers)


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).
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);
     for(i=0;i<n;i++){
         names[i]=readr();
         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;
     A[n]=NULL;
     return A;

}

char *readr(void){
     char *buf;
        int i;
     char c,BB[256]={'\0'};
     fflush(stdin);
/* Read 255 characters max. Last char is '\0': */
     for(i=0; ((c=getchar())!='\n')&&i<255; i++)
             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;
     }

}

/* Should reallocate "names" and add one more entry to it :*/
void myadd(char **A){
     int n;
/* Count rows of array :*/
     for(n=0;A[n];n++);
/* It is supposed to reallocate "names" but it seems to break it */
     if((A=(char **)realloc(A, (n+2)*sizeof(*A)))==NULL)
         printf("Oops, can't reallocate mem.!\n");
     A[n]=readr();
     A[n+1]=NULL;

Piotrek wrote:

> 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).
> I left my code as it is.

> #include "stdafx.h"             /* contains stdio.h */

Then use stdio.h.  You never listed stdafx.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);

Alloca returns void*.  You don't need (or want) the cast.

>      for(i=0;i<n;i++){

Try including a few spaces between items. "for (i = 0; i < n; i++)"

>          names[i]=readr();
>          printf("txt: %s\n", names[i]);
>      }

>      myadd(names);
>      myfree(names);
>         return 0;
> }

> /* Functions */

Better to precede main with these, thus dispensing with the
prototypes.  This technique reduces the possibility of silly
errors.

> void myfree(void *AA){          /* Free all allocated memory */
>      int i;
>      void **A=(void **)AA;

Once again, no cast.  You are doing something funny (and
unnecessary) with these pointers.

>      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;

No cast.

>      A[n]=NULL;
>      return A;
> }

I got tired of reading by now.

--
 <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
 <http://www.securityfocus.com/columnists/423>
 <http://www.aaxnet.com/editor/edit043.html>
 <http://kadaitcha.cx/vista/dogsbreakfast/index.html>
                        cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

I compiled and runed ur code with dev-c++,and added a slice of my test
code,but I don't think ur array is broken up.
what did u mean?
int main(void){
 /* Dynamically allocated array of pointers :*/
     char **names;
     int i,n=2;

     names=(char **)alloca(n);
     if(names == NULL)
     {
   printf("error,names is null!\n");
       exit(1);
 }
     for(i=0;i<n;i++){
         names[i]=readr();
         printf("txt: %s\n", names[i]);
     }

     myadd(names);
/*add my test code*/
     i = 0;
     while(names[i]){
         /*names[i]=readr();*/
         printf("txt: %s\n", names[i++]);
  }
     myfree(names);
     return 0;

}

"Piotrek" <nore@noreply.com> ??????:f3fe8r$8f@news.task.gda.pl...

On Mon, 28 May 2007 22:32:34 +0200, Piotrek <nore@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.

You need to check that alloca succeeded.

>     for(i=0;i<n;i++){
>         names[i]=readr();

You need to check that readr succeeded.

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

CBFalconer wrote:

> Piotrek wrote:
> > /* Functions */

> Better to precede main with these, thus dispensing with the
> prototypes.  This technique reduces the possibility of silly
> errors.

Which silly errors are you refering to?

--
pete

Barry Schwarz wrote:

> On Mon, 28 May 2007 22:32:34 +0200, Piotrek <nore@noreply.com>
> wrote:
> >/* Count rows of array :*/
> >     for(n=0;A[n];n++);

> Any attempt to evaluate the indeterminate value in n invokes undefined
> behavior.

He assigned a value of zero to n, in the above shown code.

> 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.

That's the ticket!

void myadd(char ***A)
{
    size_t n;
    void *p;

    for (n = 0; (*A)[n] != NULL; ++n) {
        ;
    }
    p = realloc(*A, (n + 2) * sizeof(**A));
    if (p != NULL) {
        *A = p;
        (*A)[n + 1] = NULL;
        (*A)[n] = readr();
    } else {
        puts("p == NULL");
        exit(EXIT_FAILURE);
    }

}

--
pete

Piotrek 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).
> I left my code as it is.
> Thank you!

I agree with everything that Barry Schwarz
said in his reply to your post,
except the part about indeterminate n;
I think he just didn't see the assignment to n.

/* BEGIN new.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STRINGS       2

char **alloca(size_t n);
char *readr(void);
void myadd(char ***A);
void myfree(char **A);

int main(void)
{
    char **names;
    size_t i, n = STRINGS;

    names = alloca(n);
    if (names == NULL) {
        puts("names == NULL");
        exit(EXIT_FAILURE);
    }
    for (i = 0; i != n; ++i) {
        names[i] = readr();
        printf("txt: %s\n", names[i]);
    }
    myadd(&names);
    puts("\n");
    for (i = 0; names[i] != NULL; ++i) {
        printf("txt: %s\n", names[i]);
    }
    myfree(names);
    puts("\nfreed");
    return 0;

}

void myfree(char **A)
{
     size_t i;

     for (i = 0; A[i] != NULL; ++i) {
         free(A[i]);
     }
     free(A);

}

char **alloca(size_t n)
{
    char **A;

    if ((A = malloc((n + 1) * sizeof *A)) != NULL) {
        A[n] = NULL;
    }
    return A;

}

char *readr(void)
{
    char *buf;
    size_t i;
    int c;
    char BB[256] = {'\0'};

    for (i = 0; ((c = getchar()) != '\n') && i != 255; ++i) {
        if (c == EOF) {
            puts("c == EOF");
            exit(EXIT_FAILURE);
        }
        BB[i] = (char)c;
    }
    if ((buf = malloc(i + 1)) != NULL) {
        strcpy(buf, BB);
    } else {
        puts("buf == NULL");
        exit(EXIT_FAILURE);
    }
    return buf;

}

void myadd(char ***A)
{
    size_t n;
    void *p;

    for (n = 0; (*A)[n] != NULL; ++n) {
        ;
    }
    p = realloc(*A, (n + 2) * sizeof(**A));
    if (p != NULL) {
        *A = p;
        (*A)[n + 1] = NULL;
        (*A)[n] = readr();
    } else {
        puts("p == NULL");
        exit(EXIT_FAILURE);
    }

}

/* END new.c */

--
pete

Piotrek 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).
> 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);

Just to add one minor point to the discussion. alloca() is a common
extension on many systems. It is also a built in function in gcc, so
unless you compile your program with -ansi or -std=c[89]9, your program
will fail in mysterious ways.

It's probably a good idea to rename alloca() to something else.

HTH
Bjrn

[snip]

--
Looking for an embeddable web server?
http://www.metasystems.no/products/highlander/index.html

On Tue, 29 May 2007 02:12:03 GMT, pete <pfil@mindspring.com> wrote:
>Barry Schwarz wrote:

>> On Mon, 28 May 2007 22:32:34 +0200, Piotrek <nore@noreply.com>
>> wrote:

>> >/* Count rows of array :*/
>> >     for(n=0;A[n];n++);

>> Any attempt to evaluate the indeterminate value in n invokes undefined
>> behavior.

>He assigned a value of zero to n, in the above shown code.

Yes, I missed that.  I guess horizontal white space is becoming more
than a luxury.

Remove del for email

eric liu wrote:

> I compiled and runed ur code with dev-c++,and added a slice of my
> test code,but I don't think ur array is broken up.
> what did u mean?

ur is not a legal language on c.l.c, it is an ancient Abysinian
city.  U hasn't posted here for some time.  This is not a
chat-room.

--
 <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
 <http://www.securityfocus.com/columnists/423>
 <http://www.aaxnet.com/editor/edit043.html>
 <http://kadaitcha.cx/vista/dogsbreakfast/index.html>
                        cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

pete wrote:
> CBFalconer wrote:
>> Piotrek wrote:

>>> /* Functions */

>> Better to precede main with these, thus dispensing with the
>> prototypes.  This technique reduces the possibility of silly
>> errors.

> Which silly errors are you refering to?

Anything caused by the prototype and declaration headers being
unequal.  It also means you only have to look one way to find the
function declaration.

--
 <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
 <http://www.securityfocus.com/columnists/423>
 <http://www.aaxnet.com/editor/edit043.html>
 <http://kadaitcha.cx/vista/dogsbreakfast/index.html>
                        cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc