Thread: HELP PLS!!! pointer string array run-time error

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    10

    Question HELP PLS!!! pointer string array run-time error

    Hello, I am getting an error when I run the following code: the error occurs in function printArryIIS when attempting to pring content of arrays, string pointer array to be specific:

    Error msg: NON-FATAL RUN-TIME ERROR Attempt to read beyond end of string.

    Code:
    #include <ansi_c.h>
    
    // Function prototypes
    int initArryIIS(int *iP1,int *iP2, char *strP, int max);
    int printArryIIS(int *p1, int *p2, char *strP, int max);
    
    int main(void)
    {
        int i=0;
        char str[20];
        
        char * uLimit = malloc(144 * sizeof(char));
    
        int *iPtr = (int *) malloc(10 * sizeof(int)); // allocate space for an array w/ 10 elements of type int
        int *iPtr2 = (int *) malloc(10 * sizeof(int)); // allocate space for an array w/ 10 elements of type int
    
        char *sPtr = (char *) malloc(10 * sizeof(char)); // allocate space for an array w/ 10 elements of type char
    
        char *p2str, *p3str;
        p2str = sPtr; // p2str now points to the base addresss of string array pointer sPtr
        p3str = sPtr;
            
        initArryIIS(iPtr,iPtr2,p2str,10);
        p2str = sPtr;
        printArryIIS(iPtr,iPtr2,p3str,10);
            
        getchar();
    }
    
    
    int initArryIIS(int *iP1,int *iP2, char *strP, int max)
    {
        char str[15];
        char *Ps;
        Ps = strP;
        
        for(int val=0; val<max; val++)
        {
            iP1[val] = val;  // init int pointer array: method 1  
            *(iP2+val) = val+1;  // init int pointer array: method 2
    
            sprintf(str,"string%d\0",val); // init string pointer array
            Ps =str;
            ++Ps;
        }
        return 0;
    }
    
    int printArryIIS(int *p1, int *p2, char *strP, int max)
    {
        
        for(int x=0; x<max; x++)
        {
            printf("[%d] %3d %3d %15s\n",x, *p1,*p2,strP); // NON-FATAL RUN-TIME ERROR: attempting to read beyond end of string???
            ++p1;
            ++p2;
            ++strP;
        }
        return 0;
    }

  2. #2
    Bored Programmer
    Join Date
    Jul 2009
    Location
    Tomball, TX
    Posts
    428
    Whats the value of Max?

    Honestly the variable names are rather indistinct making the code harder to read, but what does sPtr point to? I see you allocate memory but I don't see it pointing to anything.
    Last edited by Lesshardtofind; 12-09-2012 at 11:20 PM.
    Virtual reality hello world http://www.rodneybrothers.com/vr/vrh...rld/index.html in html and javascript.
    Viewable with dodocase, google cardboard, OR, and other compatible VR gear.

  3. #3
    Registered User
    Join Date
    Dec 2012
    Posts
    10
    Sorry about it not being clear. max = 10 (declared at top of program: malloc)

    I have reduced the program and make it easier to read/follow. I have also added comment to where the error occurs: see last function below. Please let me know what I'm doing wrong is trying to print the content of the string pointer array.

    Code:
    #include <ansi_c.h>
    
    // Function prototypes
    int initArryIIS(char *p, int max);
    int printArryIIS(char *p, int max);
    
    int main(void)
    {
        int i=0;
        char tempStr[20];
        
        char *pStr = (char *) malloc(10 * sizeof(char)); // allocate space for an array w/ 10 elements of type char
    
        char *pTemp;
        pTemp = pStr; // copy pStr address to pTemp pointer
            
        initArryIIS(pTemp,10); // initial string pointer array
        pTemp = pStr;
        printArryIIS(pTemp,10); // print content of array which pointer sPtr points to
        
        getchar();
        return 0;
    }
    
    
    int initArryIIS(char *p, int max)   // max = 10 string elements in array
    {
        char str[15];
        
        for(int val=0; val<max; val++)
        {
            sprintf(str,"string%d\0",val); // init string pointer array
            p =str;
            ++p;
        }
        return 0;
    }
    
    int printArryIIS(char *p, int max) // max = 10 string elements in array  
    {
        for(int x=0; x<max; x++)
        {
            printf("[%d] %15s\n",x,p); // NON-FATAL RUN-TIME ERROR: attempting to read beyond end of string???
            ++p;
        }
        return 0;
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > char *pStr = (char *) malloc(10 * sizeof(char)); //
    Well the problem seems to be that you only have space for 10 chars, not 10 strings (of 10 chars).

    You need to use these concepts.
    Code:
    char **strings = malloc( 10 * sizeof(char*) );
    
    strings[0] = malloc(10 * sizeof(char) );
    
    sprintf(strings[0],"hello %d", 123);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Bored Programmer
    Join Date
    Jul 2009
    Location
    Tomball, TX
    Posts
    428
    Man I stared at that line thinking something was wrong! But I don't quite understand the solution. I'm going to google **
    Virtual reality hello world http://www.rodneybrothers.com/vr/vrh...rld/index.html in html and javascript.
    Viewable with dodocase, google cardboard, OR, and other compatible VR gear.

  6. #6
    Registered User
    Join Date
    Dec 2012
    Posts
    10
    Ok, I did some more research and was able to figure out what I need to do for what my I was trying to do:

    1) needed a pointer pointing to an array of several string elements (e.g. 10)
    2) dynamically create memory block for this array

    therefore:
    Code:
    char * strArray[10] // points to an array of 10 string elements
    
    for(int n=0; n<10; n++)
    {
         strArray[n] = malloc(20 * sizeof(char)); // block size of 20 byte size of memory for each string
    }
    the rest a breeze
    my next challenge will be to do the same for pointer of array of struc

    Thx for helping to start the thinking process!!!

  7. #7
    Registered User
    Join Date
    Dec 2012
    Posts
    10
    OK, I created pointer of an array of structure of size 10; initialize it but when i print it is is only printing the last element for two of the members (sigName and rfConn). Can someone tell me what I am doing wrong? see code below as well as output.

    Code:
    // Rev 2: make fixes below:
    
    #include <ansi_c.h>
    
    #define MAX 10
    char * strArry[MAX]; // strArry points to an array consisting of 10 strings
    char * muxStr[100];
        
    typedef struct
    {
        char* sigName;
        char* rfConn;
        int chan;
    }mux;
    
    mux *mTable[MAX];
        
    // Function prototypes
    int initArryIIS(char *p, int i);
    int printArryIIS(char *p, int i);
    
    int main(void)
    {
        int i;
        char tempStr[20];
        
        for(i=0; i<MAX; i++)
        {   // note strArry[i] will have point to the address location of block of memory for 20 character size
            strArry[i] = malloc(20 * sizeof (char)); // create block size MAX of memory for each string element i
        }
    
        for(i=0; i<MAX; i++)
        {
            mTable[i] = malloc(25 * sizeof(mux));
        }
            
        char *pTemp;
        
        for(int n=0; n<MAX; n++)
        {
            pTemp = strArry[n];      // duplicate pointer (strArry) address
            initArryIIS(pTemp,n);  // initialize string pointer array
            printArryIIS(pTemp,n); // print content of array which pointer sPtr points to
    
            sprintf(tempStr,"REF_OUT%d\0",n);
            mTable[n]->sigName = tempStr;
            sprintf(tempStr,"J%d\0",n+1);
            mTable[n]->rfConn = tempStr;
            mTable[n]->chan = n+1;
        }
    
        printf("\n\nNo.     NAME  TYPE  CH\n==========================\n");
        for(i=0; i<MAX; i++)
        {
            printf("[%d] %9s %5s %4d\n", i, mTable[i]->sigName, mTable[i]->rfConn, mTable[i]->chan);
        }
        getchar();
        return 0;
    }
    
    
    int initArryIIS(char *p, int i)   // array size = 10 string elements in array
    {
        sprintf(p,"string%d\0",i); // init element i in string pointer array
    
        return 0;
    }
    
    int printArryIIS(char *p, int i) // array size = 10 string elements in array  
    {
        printf("[%-d]  %-15s\n",i,p);
    
        return 0;
    }
    Program OUTPUT:
    [0] string0
    [1] string1
    [2] string2
    [3] string3
    [4] string4
    [5] string5
    [6] string6
    [7] string7
    [8] string8
    [9] string9


    No. NAME TYPE CH
    ================
    (why isn't column NAME and TYPE showing duplicates and why no increment?)
    [0] J10 J10 1
    [1] J10 J10 2
    [2] J10 J10 3
    [3] J10 J10 4
    [4] J10 J10 5
    [5] J10 J10 6
    [6] J10 J10 7
    [7] J10 J10 8
    [8] J10 J10 9
    [9] J10 J10 10

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > sprintf(tempStr,"REF_OUT%d\0",n);
    > mTable[n]->sigName = tempStr;
    tempStr is just a local array, which you just keep POINTING to from all over the place (lots of aliased pointers). So when you print any of your aliases, it all seems the same.

    The only variable you need is mTable (apart from your loop variable).
    You allocate everything with
    Code:
        for(i=0; i<MAX; i++)
        {
            mTable[i] = malloc(25 * sizeof(mux));
            mTable[i]->sigName = malloc(30);  // however many you need
            mTable[i]->rfConn = malloc(10);  // however many you need
        }
    Then later on, just do
    Code:
            sprintf(mTable[n]->rfConn,"J%d",n+1);
    You have too many "temp" strings all over the place confusing the issue.

    One more thing, you don't need the trailing \0 in your sprintf strings - you get that for free.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Dec 2012
    Posts
    10

    Lightbulb

    Salem thanks a lot for your help!!!

    So in summary, I not only need to allocate memory for the array of structures but also the members within the structure. And since these members were not pointing to any predefine chuck of memory they were simply retaining the last update of temp string. Finally is it the rule of thumb that you done need to add NULL when copying string to a ptr but only to a char string?

  10. #10
    Registered User
    Join Date
    Nov 2012
    Posts
    4
    Quote Originally Posted by Cpgm View Post

    therefore:
    Code:
    char * strArray[10] // points to an array of 10 string elements
    
    for(int n=0; n<10; n++)
    {
         strArray[n] = malloc(20 * sizeof(char)); // block size of 20 byte size of memory for each string
    }
    the rest a breeze
    my next challenge will be to do the same for pointer of array of struc

    Thx for helping to start the thinking process!!!
    Remember you need to free() these things. Sometimes I find it easier to just make a double array:

    Code:
    char strArray[10][20];
    Because it saves me from writing two for loops (one for freeing and one for allocating), and if you make it an automatic variable, without using malloc, then you won't forget to free() it which would give you a memory leak.

    Same thing for an array of structs, you can usually just make an array of them (unless they have string pointers inside, you'll have to allocate those separately).

  11. #11
    Registered User
    Join Date
    Dec 2012
    Posts
    10

    Lightbulb

    Andrew, good points and thanks for the reminder on releasing memory after use. Though the malloc method requires 2 steps it allows for better management of memory/resource and code running better. At least I think that's the case.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Yes, that's basically it.
    Whenever you have a * in your data declarations, you need to be thinking about where the memory is coming from.

    Regarding the nul thing, I was just commenting that "string constant\0" is functionally just the same as "string constant". The only difference is that it adds an extra \0 (waste of memory) to the string constant, but it has no effect on the operation of printf/scanf/str... functions.
    Code:
    char *a = "fred\0";
    char *b = "barney";
    char c[] = "wilma\0";
    char d[] = "betty";
    char e[4] = "dino"; // C only, illegal in C++
    Note that e does NOT have a \0 on the end of it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 04-26-2012, 03:23 PM
  2. Run-time error allocating 3-D array
    By OceanDesigner in forum C++ Programming
    Replies: 2
    Last Post: 10-22-2005, 02:02 AM
  3. Run-time error with dynamically allocated 3-D array
    By OceanDesigner in forum C Programming
    Replies: 2
    Last Post: 10-21-2005, 02:29 PM
  4. string to pointer array
    By pankleks in forum C Programming
    Replies: 7
    Last Post: 02-09-2005, 06:45 AM
  5. run time error-pointer assign
    By Micko in forum C++ Programming
    Replies: 6
    Last Post: 12-09-2003, 01:04 PM

Tags for this Thread