Несовместимый указатель на целочисленную ошибку преобразования

Я пытаюсь узнать c, где основная функция вызывает какую-то другую функцию, возвращающую массив (например, строкового типа).

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

char* array_return(char* name);

int main(){
    char* name="orange";
    char* A;
    A=array_return(name);
    free(A);

    printf("%s\n","Check stored values in A");
    int k,n;
    n=10;
    for (k=0; k < n; k++) {
        printf("%s\n",A[k]);
    }

    return 0;
}


char* array_return(char* name){
    int k,n;
    n=10;
    char* A=malloc(n);
    char string[100];

    printf("%s\n","Store values in A");
    for (k=0; k < n; k++) {
        strcpy(string,"Numer of ");
        strcat(string,name);
        strcat(string," are: ");
        sprintf(string,"%s %i",string,k);
        A[k]=string;
        printf("%s\n",A[k]);
    }
    printf("%s\n","--------------------------");
    return A;
}

Я пытаюсь сохранить следующие значения в массиве "A":

Numer of orange are:  0
Numer of orange are:  1
Numer of orange are:  2
Numer of orange are:  3
Numer of orange are:  4
Numer of orange are:  5
Numer of orange are:  6
Numer of orange are:  7
Numer of orange are:  8
Numer of orange are:  9

Однако я получаю следующие предупреждения

warning: format specifies type 'char *' but the argument has type 
'char'

incompatible pointer to integer conversion assigning to 'char'
  from 'char [100]' [-Wint-conversion]

И я получаю следующую ошибку при запуске программы:

Segmentation fault: 11

Я был бы очень благодарен, если бы кто-нибудь помог мне отладить этот код.


person Curiosity    schedule 21.06.2017    source источник
comment
Вы не можете передать массив в/из функции. Но вы можете передать указатель. Прочитайте Как спросить и используйте отладчик.   -  person too honest for this site    schedule 21.06.2017
comment
В вашем коде много проблем.   -  person BLUEPIXY    schedule 21.06.2017
comment
например, строкового типа в C нет строкового типа.   -  person alk    schedule 21.06.2017
comment
@Olaf в коде, возможно, я ошибся, но я думаю, что A - это указатель в функции array_return.   -  person Curiosity    schedule 21.06.2017
comment
@Curiosity: в своем заголовке вы хотите вернуть массив строк. Обычно это массив массивов или массив указателей. Ничего из этого нет в вашем коде. И мы не служба отладки.   -  person too honest for this site    schedule 21.06.2017
comment
@ Олаф, ты очень помог. спасибо!   -  person Curiosity    schedule 21.06.2017
comment
пример исправления   -  person BLUEPIXY    schedule 21.06.2017
comment
Ссылаясь на это sprintf(string,"%s %i",string,k);: From man sprintf: DESCRIPTION [...] C99 и POSIX.1-2001 указывают, что результаты не определены, если вызов sprintf() , snprintf(), vsprintf() или vsnprintf() вызовет копирование между перекрывающимися объектами (например, если целевой массив строк и один из предоставленных входных аргументов ссылаются на один и тот же буфер).   -  person alk    schedule 21.06.2017
comment
Отнеситесь серьезно к предупреждениям компилятора. Исправьте код, пока не перестанут появляться предупреждения. Не отбрасывайте слепо предупреждения.   -  person alk    schedule 21.06.2017
comment
Также не рекомендуется читать оттуда, куда указывает указатель free()ed.   -  person alk    schedule 21.06.2017


Ответы (1)


Так что проблем с вашим кодом много. Тот, который связан с вашим сообщением об ошибке, связан с тем, что A[k] не является строкой, и вы пытаетесь распечатать ее как одну.

printf("%s\n",A[k]);

A[k] является k элементом памяти, на который указывает A, и поскольку A объявлен как char *, это означает, что A[k] имеет тип char. Чтобы сделать то, что вы пытаетесь сделать, вы хотите, чтобы A фактически было объявлено как char **, как это.

char **A=malloc(sizeof(*A)*n); // We need n lots of what A points to

Но ваш код по-прежнему технически не работает, потому что присвоение string A[k] просто копирует то, на что указывает string, в каждый элемент A, поэтому все они будут одинаковыми. То есть до тех пор, пока эта функция не завершится, а затем вы войдете в область неопределенного поведения, поскольку память, используемая string, больше недействительна.

Итак, что вам нужно сделать, так это скопировать строку из string в новую строку, на которую указывает A[k]. Самый простой способ сделать это — использовать strdup, так как это выделит место для вашей строки и скопирует ее за один вызов функции.

A[k]=strdup(string);

В качестве альтернативы вы можете полностью отказаться от string и выделить память для A[k] и встроить в нее нужную строку.

person Chris Turner    schedule 21.06.2017
comment
Спасибо @Chris за ваши предложения и разъяснения. - person Curiosity; 21.06.2017