Подтвердить что ты не робот

Инициализация массива целочисленного указателя в C

У меня есть некоторые путаницы/проблемы об использовании указателей в C. Я поставил примерный код ниже, чтобы понять его легко. Обратите внимание на различия этих кодов. Если у вас есть проблемы с пониманием этого вопроса, пожалуйста, обратитесь к нам.

Это не работает.

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

void process() {
    int *arr;
    arr=(int*)malloc(5*sizeof(int));
    arr=(int*){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

Но это работает.

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

void process() {
    int *arr;
    arr=(int*)malloc(5*sizeof(int));
    arr=(int[]){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

Это тоже работает. Зачем? Я не выделял здесь память.

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

void process() {
    int *arr;
    arr=(int[]){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

Почему они не такие?

    arr=(int*){3,1,4,5,2};
    arr=(int[]){3,1,4,5,2};

Есть ли другой способ инициализации массива целочисленного указателя, не используя этот индивидуальный способ назначения?

arr[0]=3;
arr[1]=1;
arr[2]=4;
arr[3]=5;
arr[4]=2;

Как я могу получить размер/количество размещения в памяти указателя, чтобы я мог использовать что-то вроде for(int z=0;z<NUM;z++) { вместо for(int z=0;z<5;z++) { статически?

Любой ответ высоко оценен.

Спасибо заранее.

4b9b3361

Ответ 1

Когда вы говорите: ptr = {1,2,3,4,5}, вы делаете ptr указывать на память в сегменте данных, где находится постоянный массив {1,2,3,4,5}, и, таким образом, вы пропускаете память. Если вы хотите инициализировать свою память, сразу после выделения, напишите: ptr[0]=1; ptr[1]=2; и так далее. Если вы хотите скопировать данные, используйте memcpy.

Ответ 2

Вызов malloc в первых нескольких примерах выделяет блок памяти и назначает указатель на эту память на arr. Как только вы снова назначаете arr, значение указателя перезаписывается, и вы потеряли эту выделенную память, т.е. Просочились. Это ошибка там.

Другими словами, если вы выделяете блок памяти с помощью malloc(), тогда вы можете записать в него данные с использованием синтаксиса массива (например):

int* arr = (int *) malloc(sizeof(int) * 5);
for (int i=0; i<5; ++i)
    arr[i] = i;

Но вы не можете назначить что-либо другое непосредственно arr, иначе вы потеряете указатель на этот блок памяти. И когда вы выделяете блок с помощью malloc(), не забудьте удалить его с помощью free(), когда вам это больше не понадобится.

Массив не является указателем на целое; это массив. Имя массива называется "распадаться на указатель", когда вы передаете его в качестве аргумента функции, принимающей указатель в качестве аргумента, но это не одно и то же.

Что касается вашего последнего вопроса: на самом деле разница между массивом и указателем на тип: компилятор знает размер массива, но он не знает размер блока, на который указывает произвольный указатель на -тип. Ответ, к сожалению, нет.

Но так как вы пишете С++, а не C, вы все равно не должны использовать массивы: используйте ` std::vector '! Они знают свою собственную длину, плюс они расширяемы.

Ответ 3

Список значений, разделенных запятыми, представляет собой конструкцию для инициализации массивов. Он не подходит для инициализации указателей на массивы. Для этого вам понадобится (int[]) - он сообщает gcc создать неназванный массив целых чисел, который инициализируется с предоставленными значениями.

gcc не позволит вам потерять информацию, которая arr является массивом, если вы действительно этого не хотите. Вот почему вам нужен актерский состав. Лучше объявить arr как массив, а не как указатель. Вы все равно можете передать его функциям, принимающим указатель. Однако gcc не позволит вам утечки памяти с помощью malloc:

error: incompatible types when assigning to type ‘int[5]’ from type ‘void *’

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