Инициализация массива целочисленного указателя в 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++) {
статически?
Любой ответ высоко оценен.
Спасибо заранее.
Ответы
Ответ 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 *’
Если вам нужна переменная, которая может быть либо массивом, либо указателем на выделенную память, создайте для этого другую переменную. Еще лучше создайте функцию, которая принимает указатель и передает ему либо массив, либо указатель.