0

I have this code

int main()
{


char **ppi;
ppi = malloc(sizeof(char *)*1);
ppi[0] = malloc(sizeof(char)+1);
ppi[1] = malloc(sizeof(char)+1);
ppi[2] = malloc(sizeof(char)+1);
strcpy(*ppi,"1");
strcpy(*(ppi+1),"2");
strcpy(*(ppi+2),"3");
printf("%s %s %s\n", *ppi,*(ppi+1),*(ppi+2));

char *pp[1];
pp[0]=malloc(sizeof(char)+1);
pp[1]=malloc(sizeof(char)+1);
pp[2]=malloc(sizeof(char)+1);

strcpy(*pp,"1");
strcpy(*(pp+1),"2");
strcpy(*(pp+2),"3");
printf("%s %s %s\n",*(pp+0),*(pp+1),*(pp+2) );
  /*char *(*tags)[2] = malloc (20 * sizeof *tags);
  for(int i=0;i<20;i++)
  {
    *(*(tags+i)+0)=*(tags_v+i);
    tags[i][1]=tags_t[i];
    //printf("%s %s \n",*(*(tags+i)+0),*(*(tags+i)+1));
  }*/
//  printf("%s\n",(*tags_1)[0]);
  return 0;
}

But I am getting error stack smashing detected I believe this is wrong pp[2]=malloc(sizeof(char)+1); or any access after this line at index 2 for pp array of pointers. But I can easily increase number of elements for pointer to pointer. Does this mean even array of pointers are kind of pointers but they are also array so increase number of elements can cause problems like stack smashing etc.

And can I get out of this error with array of pointers some how without not using array of pointers? I believe its stack error, probably because indexes are stack based for array of pointers. what if I create my array of pointers as global?

this question is related do I need to allocate space for pointer as well as space for memory area whose address will be kept in pointer in pointer to pointer and realloc

user786
  • 3,902
  • 4
  • 40
  • 72
  • 4
    I don't understand the question. You're causing undefined behavior by writing to array elements that haven't been allocated. – Barmar Nov 03 '21 at 04:56
  • @Barmar ok see the related question in my question and please tell do I need to must allocate space for pointers as well as space for string https://stackoverflow.com/questions/69820362/do-i-need-to-allocate-space-for-pointer-as-well-as-space-for-memory-area-whose-a – user786 Nov 03 '21 at 07:49
  • 1
    You are merely accessing this stack-allocated array `char *pp[1];` out of bounds. Only `pp[0] = malloc ...` is valid, the rest is not. It should have been declared as `char* pp[3];` if you mean to access indices 0,1 and 2. – Lundin Nov 03 '21 at 10:13

1 Answers1

0

If the question is "do i need to allocate space for ..." the answer is yes and no. The real question is, what is meant by 'allocation'.

Storage can be allocated on the stack (automatic allocation via declaration) or on the heap (malloc and friends).

A pointer is simply a storage that holds the address of a specific memory block. As said before, the address variable (pointer) can also be allocated on the stack or on the heap.

Example:

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

int main()
{
    //stack allocation
    int i = 42;

    //store the address of the variable 'i' in 'pi'
    void *pi = &i; //<- 'pi' is allocated on the stack

    //print the value of the address to stdout
    printf("the address of i: %p\n", pi);

    //store the address of the variable 'pi' in 'pp' (example of pointer to pointer)
    void *pp = &pi; //<- 'pp' is allocated on the stack
    printf("the address of pi: %p\n", pp);

    //here we have two allocations:
    //- 'ptr' is allocated on the stack
    //- malloc allocates 1 byte on the heap and returns the address of that memory block, which is stored in 'ptr'
    void *ptr = malloc(1);

    printf(
        "the address of ptr: %p\n"
        "the address of the allocated memory area: %p\n", 
        &ptr,
        ptr
    );

    //allocate storage on the heap large enough to hold a pointer
    void **pptr = malloc(sizeof(void*)); //'pptr' is allocated on the stack
    //allocate 1 byte on the heap and store the address in the memory area from above
    *pptr = malloc(1);

    printf(
        "the address of pptr: %p\n"
        "the address of the allocated memory to store the pointer: %p\n" 
        "the address that is stored in pptr (via malloc(1)): %p\n",
        &pptr,
        pptr,
        *pptr
    );

    //array of pointer of size 3
    void *pa[3]; //heap version: malloc(sizeof(void*) * 3)
    pa[0] = malloc(1);
    pa[1] = malloc(1);
    pa[2] = malloc(1);

    printf(
        "address of the array: %p\n"
        "address of the first element: %p\n"
        "address of the second element: %p\n"
        "address of the third element: %p\n"
        "address stored in the first element: %p"
        "address stored in the second element: %p"
        "address stored in the third element: %p",
        &pa, &pa[0], &pa[1], &pa[2], pa[0], pa[1], pa[2]
    );

    return 0;
}

The problem of stack smashing / buffer overflow:

//declare a pointer to pointer to char
char **ppi; 
//allocate space large enough to hold a (one) pointer to char
ppi = malloc(sizeof(char *)*1);
ppi[0] = ... //ok, same as *ppi
ppi[1] = ... //not ok, we allocated space only for 1 (one) pointer
ppi[2] = ... //not ok, we allocated space only for 1 (one) pointer

and

//allocate an array of pointers to char on the stack, with size of 1 (one)
char *pp[1];
pp[0] = ... //ok, array has size 1
pp[1] = ... //not ok, array has size 1
pp[2] = ... //not ok, array has size 1
Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11