![]() |
Перераспределение памяти - realloc
Здравствуйте, Уважаемые.
Честно говоря, даже немного стыдно с таким вопросом выходить, но уже сколько бьюсь, никак не могу решить - не понимаю. Задача элементарнейшая - надо перераспределиить память и увеличить массив еще на один элемент. Лучше сразу покажу код: Код:
#include <iostream> НО, у меня все падает с сигналом SIGABRT. Пожалуйста, объясните что я делаю не так и как надо? Да, на всякий случай, компилятор - gcc-4.4.1 Вроде как все правильно |
Во-первых, если тебя интересует почему падает с SIGABRT - потому что ты пытаешься перевыделить память по указателю argv, который любезно сформирован для тебя библиотекой CRT и является указателем на массив строк аргументов командной строки, а argc - их числом, и использовать realloc по указателю *argv (вообще каким-то образом изменять эти переменные) неверно.
Теперь - твой realloc по *argv будет перевыделять память по указателю на первую строку из этого массива - т.е., если мы запускаем программу без аргументов, то это будет указатель на строку с именем файла - а чтобы добавить элемент в подобный массив строк тебе надо использовать функцию примерно так: Код:
argv = (char**)realloc( argv, sizeof(char*) * (++(*argc)) ); |
нет,
Цитата:
На реалкодинге высказали мысль, что его менять вообще нельзя - http://forums.realcoding.net/index.php?showtopic=23479 |
Цитата:
Эти переменные нельзя изменять! Прочитай в интернете что-нибудь про библиотеку CRT и вызов функции main() - узнаешь как оно все устроено ;) |
L0rd, как добавить в подобный массив, я и так знаю, и привел выше пример. Меня интересует конкретная проблема, поставленная в первом посте. Что вообще нужно искать ответ в CRT и стандартах C/C++ я знаю и без Вас. Поэтому, если есть конкретные предложения, решения, мысли, ссылки (на те же стандарты, где описано по этому поводу) - велкам. А просто писать непроверенные неработающие примеры лучше не стоит. Уж извините за резкость.
|
Например здесь можно прочитать про функцию main http://en.wikipedia.org/wiki/Main_fu...programming%29
|
L0rd, и что? Там же ни слова нету где и как выделяется память под массив argv... Или про то что его нельзя менять... Или я плохо читал?
|
Цитата:
Соответственно, SIGABRT - совершенно нормальное явление. Винда в таком случае говорит "Программа выполнила недопустимую операцию и будет закрыта". И это правильно - насколь мне известно, любая ОС может позволить приложению читать "чужую" память и даже писать туда, но не перераспределять её. Т.е. если так необходимо перераспределить память под argv - необходимо не "решать" задачу в лоб, а ковырять API процесса-владельца на предмет заставить выполнять соответствующую задачу его. Это насколько я помню основы системного программирования... |
Борланд, не уверен что память под argv выделяется до запуска программы... Не в CRT это разве должно делаться?
Цитата:
Цитата:
|
Цитата:
В любом случае, функцию realloc можно вызывать только, если по заданному указателю уже была выделена память с помощью malloc/realloc - и никак иначе. А доступ на запись в переменные argc м argv просто-напросто может быть блокирован самой библиотекой CRT - хотя бы для того, чтобы пользователь не мог ничего испортить внутри самой библиотеки CRT. Цитата:
|
Цитата:
Цитата:
Цитата:
|
Хм, ну в общем поковырялся немного с дебаггером.
Нету никакого mainCRTStartup()! Упоминания его есть только в mingw компиляторе, то есть в кросс-компилере под винду. Теперь что касается реального положения вещей, раз уж все оказалось не так, как описал L0rd, выше, если вдруг кому интересно (я пишу частный случай про изначально указанный GCC-4.4.1, glibc-2.10.1-4.i586, Linux Kernel - 2.6.31 на своей системе, не будучи специалистом в этой теме совершенно не претендую на истину этого на любой другой ОС или компонентах): Соответственно main вызывается из функции __libc_start_main. Аргументы argc и argv инициализируются вот как-то так: https://www.codeblog.org/viewsrc/gli...bp-start.h#l28 проходя через "магические" вызовы __preinit_array_start(), __preinit_array_end(), __init_array_start(), __init_array_end(), __fini_array_start(), __fini_array_end(), которые в свою очередь формируются линкером, согласно комментам. Вызываются они из __libc_csu_init, ссылка на который передается __libc_start_main как параметр init. Возвращаясь к начальной проблеме, получается что argv выделяется при помощи alloca, а не стандартных malloc, calloc и видимо, действительно не может быть ими перераспределен. |
Часовой пояс GMT +4, время: 00:10. |
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.