2012-03-15 3 views
3

Я пишу метод, который получает число l и возвращает вектор размера l со случайными числами. У меня есть этот код, но не работаетC - функция возвращает массив

#include <time.h>  

int makea (int z) { 
    int a1[z]; 
    int i; 

    for (i = 0; i < tam; i++) { 
     a1[i]=srand(time(0)); 
    } 
    return a1; 
} 

Эти ошибки, компилятор возвращает мне

arrays1.c: In function 'makea':
arrays1.c:12: error: void value not ignored as it ought to be
arrays1.c:14: warning: return makes integer from pointer without a cast
arrays1.c:14: warning: function returns address of local variable

Я думаю, это проблема указателей ... но я не совсем уверен,

+2

Вы _can't_ возвращаете массивы из функций в C, вам нужно вернуть указатель на массив. Попробуйте использовать malloc для создания массива. –

+1

Прежде всего, это очень простой вопрос и ответ в любой книге C (K & R, c-faq). 2) когда вы выдаете сообщение об ошибке, убедитесь, что вы помечаете строки (12,14) в коде (скопируйте и вставьте из IDE или сделайте это вручную). – AoeAoe

+0

Btw, C не использует «методы», он использует функции. – AoeAoe

ответ

6

Нескольких проблем:

  1. Ваш массив выделяются в стеке, а это означает, что, когда ваш выход из функции, память вы вернетесь будет недействительна
  2. В C, вы не можете вернуть массив из функции , он должен сначала распадаться на указатель.

Таким образом, чтобы исправить, используйте таНос и указатель:

int *makea (int z) { 
    int *a1 = malloc(sizeof(int) * z); 
    int i; 

    srand(time(NULL)); 
    for (i = 0; i < tam; i++) { 
     a1[i]= rand(); 
    } 

    // remember to free a1 when you are done! 
    return a1; 
} 

Также обратите внимание, что при использовании таНоса может иногда в основном предоставить вам сценарий «случайное число» бесплатно, что устраняет необходимость в цикл через элементы, поскольку значение, возвращаемое из malloc, является мусором (и, следовательно, случайными числами).

Однако также обратите внимание, что malloc является специфичным для реализации, что означает, что реализация может теоретически очистить память перед вами, прежде чем возвращать ее.

+0

Malloc не обязательно возвращает указатель на мусор. В некоторых системах нераспределенная память кучи устанавливается на определенное значение при запуске, чтобы помочь отлаживать. В зависимости от причины заполнения массива случайными данными может быть совершенно необходимо сделать это. –

+1

@ChrisBrowne правильно, я обновил свой пост до того, как вы его прокомментировали, очевидно, что он не обновил серверную сторону. –

+0

'srand' используется для засева генератора и не возвращает значения. Я понимаю, что вы просто используете код OP, но только для того, чтобы быть правильным ... –

0

Ну, во-первых, ваша функция говорит, что она возвращает int, но вы хотите вернуть массив, так что это неправильно. Конечно, вы не можете вернуть массив в C либо ...

Во-вторых, вам нужно будет вернуть указатель. Вы не можете копировать массивы с помощью назначения или назначать новое значение для массива вообще на C, поэтому ваша функция будет не очень полезной. Либо верните int*, либо возьмите int** в качестве выходного аргумента и инициализируйте его в своей функции.

Кроме того, ваш массив локально выделен, поэтому даже если компилятор не жаловался, вы возвращаете неверную память.

int makea (int size, int **out_array) { 
    int *temp, i; 
    if(!out_array) 
     return 0; 
    temp = malloc(sizeof(int) * size); 
    if(!temp) 
     return 0; 

    srand(time(0)); 
    for (i = 0; i < size; ++i) 
     temp[i] = rand();   

    *out_array = temp; 
    return 1; 
} 

int main() { 
    int *arr; 
    if(!makea(10, &arr)) { 
     printf("Failed to allocate array"); 
     return -1; 
    } 

    return 0 
} 

Еще одно замечание:

temp[i] = srand(time(0));   

Это неправильно. srand сгенерирует генератор случайных чисел, но не возвращает случайное число. Вы вызываете srand для ввода семени, а затем звоните rand, чтобы получить случайное число.

1

Ваш лучший выбор:

  1. Объявите массив за пределами рутины, и передать его в инициализации:

    void init_array (int a[], nelms)

  2. Plan B является передать указатель на указатель и назначить его подпрограмму

Как это:

void alloc_and_init_array (int **a_pp, int nelms) 
{ 
    *a_pp = malloc (sizeof (int) * nelms); 
    ... 

... или, что то же самое ...

int * 
alloc_and_init_array (int nelms) 
{ 
    int *a_p = malloc (sizeof (int) * nelms); 
    ... 
    return a_p; 
+0

@patz (2) решает вопрос как поставленный, но серьезно посмотрите, работает ли (1) для вас. С помощью (2) используйте возвращаемое значение, чтобы отметить успешное создание массива. – Keith

0

Локальная переменная, как ваш массив выделяется в стеке. При возврате функции он удаляется из стека, поэтому возвращаемый указатель указывает на нераспределенную ячейку памяти.

Вы должны выделить массив с помощью malloc() или передать уже существующий массив функции.

0
#include <time.h>  

int makea (int z) { 
    int *a1 = (int*)malloc(z*sizeof(int)); 
    int i; 

    for (i = 0; i < tam; i++) { 
     a1[i]=srand(time(0)); 
    } 

    return a1; 
} 

ВАЖНО: не забудьте освободить память, расположенную где-то снаружи, когда она вам больше не понадобится.

Смежные вопросы