Думаю, я дошел до самого простого случая:
int main(int argc, char ** argv) {
int * arr;
foo(arr);
printf("car[3]=%d\n",arr[3]);
free (arr);
return 1;
}
void foo(int * arr) {
arr = (int*) malloc( sizeof(int)*25 );
arr[3] = 69;
}
Результат такой:
> ./a.out
car[3]=-1869558540
a.out(4100) malloc: *** error for object 0x8fe01037: Non-aligned pointer
being freed
*** set a breakpoint in malloc_error_break to debug
>
Если кто-то может пролить свет на то, где мое понимание не работает, я был бы очень признателен.





Вы выделили массив в футах, но это значение указателей хранится в стеке вызовов. Если вы хотите это сделать, сделайте это так:
void foo( int ** arr) {
*arr = (int *)malloc( sizeof(int) * 25 );
(*arr)[3] = 69;
}
И в основном просто передайте указатель на foo (например, foo (& arr))
Вы передаете указатель по значению, а не по ссылке, поэтому все, что вы делаете с arr внутри foo, не будет иметь значения за пределами foo-функции. Как писал m_pGladiator, один из способов - объявить ссылку на указатель, подобный этому (возможно только в C++, кстати. C не знает о ссылках):
int main(int argc, char ** argv) {
int * arr;
foo(arr);
printf("car[3]=%d\n",arr[3]);
free (arr);
return 1;
}
void foo(int * &arr ) {
arr = (int*) malloc( sizeof(int)*25 );
arr[3] = 69;
}
Другой (лучший imho) способ - не передавать указатель в качестве аргумента, а вернуть указатель:
int main(int argc, char ** argv) {
int * arr;
arr = foo();
printf("car[3]=%d\n",arr[3]);
free (arr);
return 1;
}
int * foo(void ) {
int * arr;
arr = (int*) malloc( sizeof(int)*25 );
arr[3] = 69;
return arr;
}
И вы можете передать указатель на указатель. Это способ передачи C по ссылке. Немного усложняет синтаксис, но хорошо - вот как устроен C ...
int main(int argc, char ** argv) {
int * arr;
foo(&arr);
printf("car[3]=%d\n",arr[3]);
free (arr);
return 1;
}
void foo(int ** arr ) {
(*arr) = (int*) malloc( sizeof(int)*25 );
(*arr)[3] = 69;
}
@freespace, это привычка, которую я выработал за долгие годы. Каждый раз, а затем я должен отправить свой код через инструменты статического анализа кода, и они жалуются, что не приводят указатели.
Извините, что оставил вас висеть без ответа: нет хорошего способа найти ответы в комментариях, если я не опрошу все свои комментарии :) Я оставил ответ в stackoverflow.com/questions/108768/…
@freespace, я знаю - надеюсь, что когда-нибудь будет добавлена возможность уведомлять через комментарии.
Какой из первых двух методов является наиболее быстрым для выделения памяти с помощью функции?
Вы не можете изменить значение вашего аргумента (arr), если оно не передано по ссылке (&). В общем, вы хотите вернуть указатель, поэтому ваш метод должен быть:
arr = foo ();
Плохо пытаться переназначить аргументы; Я не рекомендую решение (&).
foo получает локальную копию указателя int, выделяет ему память и пропускает эту память, когда выходит за пределы области видимости.
Один из способов исправить это, чтобы foo возвращал указатель:
int * foo() {
return (int*) malloc( sizeof(int)*25 );
}
int main() {
int* arr = foo();
}
Другой - передать foo указатель на указатель
void foo(int ** arr) {
*arr = malloc(...);
}
int main() {
foo(&arr);
}
В C++ проще изменить foo, чтобы он принимал ссылку на указатель. Единственное изменение, которое вам нужно в C++, - это заменить foo на
void foo(int * & arr)
Поскольку вы передаете указатель по значению, указатель arr внутри main не указывает на выделенную память. Это означает две вещи: у вас есть утечка памяти (НЕТ, память не освобождается после завершения функции foo), и когда вы обращаетесь к указателю arr внутри main, вы получаете доступ к некоторому произвольному диапазону памяти, поэтому вы не 't получить 3 распечатанных и, следовательно, free () отказывается работать. Вам повезло, что вы не получили ошибку сегментации при доступе к arr [3] внутри main.
Могу я просто сказать, пожалуйста, не приводите возвращаемое значение malloc? Это не обязательно и может скрыть ошибки.