0

I was trying out a simple program to understand how to use a pointer to an array of pointers to structure.

I wrote this small program:

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

struct A
{
   char* a1;
};

void fn1(A **d, int n)
{
    printf("5 \n");
    for(int i=0;i<n;i++)
    {
        printf("val: %s \n",d[i]->a1);
    }
    printf("6 \n");
}
int main(int argc, char **argv) {
    printf("0 \n");
    A *a,*b,*c;
    printf("1 \n");
    a = (A*)malloc(sizeof (A));
    b = (A*)malloc(sizeof (A));
    c = (A*)malloc(sizeof (A));
    printf("2 \n");
    a->a1 = "hi";
    b->a1 = "bye";
    c->a1 = "see you";
    printf("3 \n");
    A *d[] = {a,b,c};
    printf("4 \n");
    fn1(d,3);
    printf("7 \n");
    printf("Program successfully completed \n");
}

The program compiled and executed properly and I got this output:

0 
1 
2 
3 
4 
5 
val: hi 
val: bye 
val: see you 
6 
7 
Program successfully completed 

But while compiling I was getting these warnings on deprecated conversion from string to char* so I decided to change the char* in my struct to std::string. I changed the program into:

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

struct A
{
   std::string a1;
};

void fn1(A **d, int n)
{
    printf("5 \n");
    for(int i=0;i<n;i++)
    {
        printf("val: %s \n",d[i]->a1.c_str());
    }
    printf("6 \n");
}
int main(int argc, char **argv) {
    printf("0 \n");
    A *a,*b,*c;
    printf("1 \n");
    a = (A*)malloc(sizeof (A));
    b = (A*)malloc(sizeof (A));
    c = (A*)malloc(sizeof (A));
    printf("2 \n");
    a->a1 = "hi";
    b->a1 = "bye";
    c->a1 = "see you";
    printf("3 \n");
    A *d[] = {a,b,c};
    printf("4 \n");
    fn1(d,3);
    printf("7 \n");
    printf("Program successfully completed \n");
}

Now The program compiled properly but I got a segmentation fault(core dumped) on running. Not even the first printf("0"); got displayed. Can anyone explain me what mistake am I doing here?

Vivek V K
  • 1,100
  • 2
  • 15
  • 33
  • 1
    `malloc` and objects that need to be constructed don't get along very well. Use `new`. – Retired Ninja Jul 17 '14 at 02:11
  • @RetiredNinja if that is the case why did not the first printf get printed? the code execution should have been normal till it executes the malloc line right? – Vivek V K Jul 17 '14 at 02:13
  • To fix the warning in your first program: in the definition of `struct A`, change to `char const *a1;` – M.M Jul 17 '14 at 02:13
  • @MattMcNabb yeah I can do that but I just said what I tried and how I got to this error – Vivek V K Jul 17 '14 at 02:15
  • 1
    Regarding the printf lines appearing: output is buffered in C++, so your program might crash before the buffered lines make it to your screen. Add `fflush(stdout);` after each `printf`. – M.M Jul 17 '14 at 02:15
  • Output through `printf` is generally buffered. Perhaps the crash happened before the buffer was flushed. – Retired Ninja Jul 17 '14 at 02:15
  • yeah fflush prints it. thanks – Vivek V K Jul 17 '14 at 02:18

1 Answers1

1

malloc is not suitable for creating non-POD objects. It allocates memory but does not call any constructors. So your line a->a1 accesses a string that has not yet been constructed, causing undefined behaviour.

To properly allocate and construct the object use:

a = new A;

It is bad style (at best) to use malloc in any C++ program

M.M
  • 138,810
  • 21
  • 208
  • 365
  • if mallocing is the problem why doesn't the first printf get printed? – Vivek V K Jul 17 '14 at 02:16
  • 1
    Output is buffered in C++, so your program might crash before the buffered lines make it to your screen. Add `fflush(stdout);` after each printf. – M.M Jul 17 '14 at 02:17