Я попробовал простую программу, чтобы понять, как использовать указатель на массив указателей на структуру.
Я написал эту небольшую программу:
#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");
}
Программа скомпилирована и выполнена правильно, и я получил этот результат:
0
1
2
3
4
5
val: hi
val: bye
val: see you
6
7
Program successfully completed
Но при компиляции я получал эти предупреждения от deprecated conversion from string to char*
поэтому решил изменить char*
в моей структуре на std::string
. Я изменил программу на:
#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");
}
Теперь программа скомпилирована должным образом, но при запуске я получил segmentation fault(core dumped)
. Даже первый printf("0");
отображается. Может ли кто-нибудь объяснить мне, какую ошибку я здесь делаю?
malloc
не подходит для создания объектов, отличных от POD. Он выделяет память, но не вызывает никаких конструкторов. Таким образом, ваша строка a->a1
обращается к строке, которая еще не построена, что приводит к неопределенному поведению.
Для правильного размещения и построения объекта используйте:
a = new A;
Плохой стиль (в лучшем случае) использовать malloc
в любой программе C++
fflush(stdout);
после каждого printf.
malloc
и объекты, которые должны быть построены, не очень хорошо ладят. Используйтеnew
.