Въпросче (C++)

16 отговора 397 прегледа
#1

Въпросче (C++)

Някой може ли да ми обясни това нещо. Значи правя масив от указатели така :

char **p = new char *[3] ;

Това би трябвало да е масив от 4 указателя. Добре ама като напиша:

p[0] = “string 0” ;
p[1] = “string 1” ;
p[2] = “string 2” ;
p[3] = “string 3” ;
p[4] = “string 4” ;
p[5] = “string 5” ;

cout << p[0] << endl ;
cout << p[1] << endl ;
cout << p[2] << endl ;
cout << p[3] << endl ;
cout << p[4] << endl ;
cout << p[5] << endl ;

си работи без проблем на release и debug (Работя с Microsoft Visual Studio 6.0).
Къде успява да набута p[5]?
После сменям
char **p = new char *[2] ;
без да променям нищо на долу и пак работи след компилация на debug. Като отида на release вече изпищява:

Unhandled exception in MyProgram.exe : 0XC0000005: Access Violation.

Въпроса може и да е тъп, но аз съм начинаещ за което се извинявам предварително.

Отговор
в отговор на нaчинaeщ #2

Re: Въпросче (C++)

Ami prosto w debug bibliotekite kogato se opredelia goleminata na bloka za allokirane se dobawia "no man lands size", koeto mislia che beshe 4 bytes (t.e. napylno dostatychno za oshte edno pointerche), t.e. coda niama da ti gyrmi pri debug. Ideata na towa neshto e che kato imash BoundsChecker naprimer toi gleda dali taia dopylnitelna pamet se overwrite-a wa i syotwetno ti kazwa che ima problem.

Moje i da gresha i se nadiawam partiinite drugari ot MS da me poprawiat ako e taka.

dimd00d
-----------
"Every time you download warez, God kills a programmer, please think about the programmers"

Отговор
в отговор на нaчинaeщ #3

Re: Въпросче (C++)

Towa e masiw ot 3 ukazatelja, a ne ot 4. Walidnite indeksi sa ot 0 do 2 wkljuchitelno.
Kogato se wzema pamet ot heap-a, brojat na bajtowete koito fakticheski se wzemat, nikoga ne e syshtia, kato tozi kojto si poiskal po razlichni prichini - minimalen razmer na bloka, informacia za samia block, guard bytes, etc.

Towa che tozi kod raboti pri opredelni uslowia e chista sluchajnost.

Отговор
в отговор на нaчинaeщ #4

Re: Въпросче (C++)

1. Броят на указателите е 3, а не 6 (!!!!)
2. След като имаш масив от указатели е редно всеки един от тях да сочи валидна памет, т.е. трябва да заделиш буфер за всеки, ето така:
for(int i=0; i<STRINGS_COUNT; i++)
p = new char[BUFF_LEN];

Я вышел им наперерез...

Редактирано от Resurrector на

Отговор
в отговор на нaчинaeщ #5

Re: Въпросче (C++)

Не, не трябва да заделяш памет (поне не и да алокираш експлицитно), стига указателите да сочат към валидна и достъпна за твоята програма памет, това което си направил с константните стрингове си е 100% валидно.
Пробвай да ползваш някакъв вид контейнери вместо обикновенни масиви (те имат лошия навик да не гарантират нищо освен правото на access) или поне wrap-ни този масив с някаква процедура за достъп:

template< class _T, int _N >
class ArrOfPtr
{
public:
ArrOfPtr() { ptr = new _T*[_N]; }
~ArrOfPtr() { delete ptr; }

_T *& operator [] ( int idx )
{
AssertSlow( idx >= 0 && idx < _N );
return ptr[idx];
}
private:
_T ** ptr;
};

Това е един (доста несъвършен) пример. Може да се разшири порядъчно и да върши прилична работа. За непосветените AssertSlow е разновидност на Assert-а която се слага в performance-критични секции, за да може да се компилира бърза, сигурна и зверски сигурна (и адски бавна) версии на софтуера.

А относно C-то: същата сигурност може и да C да се направи, но ще си счупиш прустите да я пишеш и използваш - тук C++ ти дава очевидно (синтактично) предимство.
Cheers!

The ones who live by the sword get shot by the ones who don't.
Отговор
в отговор на Zemedelec #6

Offtopic

Tozi kod shte te spasi w debug, no w release ako njakoi buffer overruner reshi da si napravi maitap s tebe - njama da raboti :) - shte ti zamaca stacka - i se nadjawam tam da ne postavi raboti.... Ama puk nali imashe nekvi StackGuard-i deto postavjaha kontrolni sumi w kraja na lokalnia stack - taka che... de da znae chovek :)

Razbira se mozhe winagi da imash wkljuchena proverkata po index i za release - ama togava koda ti stava baven :)

dimd00d da kazhe njakoa duma otnosno hackwaneto :)

ama inache e dobro reshenie! i nie tuka sme sus nekvi podobni masivcheta za njakoi ot neshtata...

tirulirutatuutuu
Отговор
в отговор на malkia #7

Re: Offtopic

Защо стека? Ще омаже каквото намери за добре, ама по идея в release не трябва да има код който открива такива неща, само по себе си ако има такъв код то автоматично ти става по-бавна програмата
Все пак това му е идеята на debug-а, да открива подобни грешки... на същия flipcode имаше един memory allocator който в debug откриваше всякакви замазвания на памет. BoundChecker по мнение на много хора не струва.
А ако в release нещо се прецака, ти явно не можеш да го спасиш - остава да except-неш и да dump-неш в log-а колкото се може повече информация за това къде и какво е злото...

The ones who live by the sword get shot by the ones who don't.
Отговор
в отговор на Zemedelec #8

Re: Offtopic

ako masiva ti se namira w steka, ili puk masiva ti e member ot obekta i obekta si go instancirash w steka.... togava mozhe da ti pomachka steka i da stane losho...

kofti che nie Bounds Checker ne mozhe da go polzwame :( - pochti nishto njama za nashia hardware - tree se wnimawa :)

Ima njakwa modifikacia na GCC-to kojato wuw wseki frame na lokalnia stack zapiswa w kraja mu edno kontrolno chislo - i kogato funkciata trebe da izleze proverjawa dali tova chislo e sushtoto - ako ne - znachi stacka e zamacan - i diretkno -> abort() - ako njama podobna proverka naprimer - razni intruderi mogat da se wuzpolzwat... edin pich mi smaza taka mIrc-to predi wreme....

w sluchaia na choveka - toj si alokira dinamichno - zatova go drupnah offtopic :) -

tirulirutatuutuu
Отговор
в отговор на malkia #9

Re: Offtopic

Искаш да кажеш - програмата да стане една идея по-сигурна?
Това за mIrc-то просто значи че си е insecure софтуера, иначе едни такива проверки само трябва да ти помогнат да debug-ваш или пък да гръмне release-то колкото се може по-близо до грешката за да е полезен log-a... да, като се замисля има хляб в това със стека. Но това може да се избегне като просто всякакви видове контейнери ги алокираш само в динамичната памет (с някакъв добър small memory manager), нали проблема е в тях.

The ones who live by the sword get shot by the ones who don't.
Отговор
в отговор на malkia #10

Re: Offtopic

Znachi sega kato poglednah no-man-land se prawi predi i sled bloka koito se alokira po 4 bytes. Picha kato ima 3 pointera i ryga 5 rabotata stawa tochna (t.e. raboti niakak si - omazwa si kraia na bloka + nachaloto na sledwashtia za po-weselo obache wse oshte w guard zonata).

Ideata malyk e che guard zonite se pylniat s constanta deto sled towa se checkwa dali e syshtata (ia ot memory managera - kakto e w sluchaia s CodeWarrior, ia ot 3rd party tool) - i ako e razlichno niakoi znachi neshto e osral.

Po wyprosa za boundschecker - chesto sym go polzwal i do sega winagi mi e pomagal (kakto i razni drugi wseizwestni tools na numega ama te sa za druga rabota) :)

dimd00d
----------
When you download warez, God kills another programmer, please think about the programmers

Отговор
в отговор на malkia #11

Re: Offtopic

Che wie ne polzwate li CW? toi si ima #define za taia cel (wij w rykowodstwoto che ne mi se tyrsi w momenta :) ) i w debug build pere na consolata ako si omazal neshto.

Отговор
в отговор на Zemedelec #12

Re: Въпросче (C++)

E to si alokira pamet chinno zashtoto toi prawi new[3], a za towa che ne gyrmi prosto go spasiawat guard bytowete.


Kakto i da e, moje ti da goworish za drugo a az prosto poludiawam (tuka zaradi edni gluposti weche minaha 48h ot kakto sym spal :( )

dimd00d
----------
When you download warez, God kills a programmer, please think about the programmers

Отговор
в отговор на dimdOOd #13

Re: Offtopic

polzwame go mnogo malko - samo da proverim dali gamecube build-a se kompilira i raboti... Az pisah pod nego za dve sedmtizi - i samo IDE_to malko me nerwirashe - no se swikwa - ne e zle...

#define koj e mezhdudrugoto - i na mene ne mi se tursi (edvam gledam) - tova shte e mnogo polezno btw...

tirulirutatuutuu
Отговор
в отговор на dimdOOd #14

Memory manager!

По въпроса с Bound Checker-а: не знам точно какви са му възможностите на този софтуер, но memory manager-а който дадох за пример (автор: Paul Nettle, може да се намери на [линк]) освен че слага/проверява guard зони около блока памет, има навика по време на runtime да ги применя, което би грумнало програма която само чете от там, без да пише и теста за consistency на guard зоните би минал в случая. А ако пише и чете има шанс да ще се прецака по-рано от освобождаването на паметта. И други хитри работи правеше онзи manager, ама на който му е интересно да ходи да го види...

[линк]

The ones who live by the sword get shot by the ones who don't.
Отговор
в отговор на Zemedelec #15

Re: Memory manager!

razgledah go naburzo - navremeto ne mu oburnah vnimanie....

obache - njakoi neshta koito ne mi hareswat:

njama wuzmozhnost za specificirane otkude da alokirash na heap-a, kakuv align - neshto ot roda

new( blockSize, typeOfAlign, whichHeap ) -> mozhe samo new( blockSize ) da pravish...

ne e jasno statichnite klasovi obekti ako sa iskali pamet otkude tja shte e bila doshla? te se inicializirat predi main()-a. I po-skoro tozi memory manager e memory-wrapper - predpolagasht che usera njama da si smeni malloc()/free() funcciite - edin wid shte si polzwa tezi na c bibliotekata. Ako iskash svoi heap - svoija organizatzia - trjabwa da go napravish tova predi main()....

Ne e jasno s multithreada kak se spravja (vupreki che ne sum vidjal tuka njakoi da pravi takiva riskove - osven mozhe bi asyncrhonnite zajawki ot wtoria thread... uh?)

razbira se ima i hitri idei :)

a za Guard-a - toj samo shte predpazi heap-dynamichnata pamet - ne i stack-pametta - no tova veche dimd00d go objasni...



tirulirutatuutuu
Отговор
в отговор на malkia #16

Re: Memory manager!

Да, това е wrapper на malloc/realloc/free, няма align и top-bottom алокации.
Това с top-bottom май само в game-индустрията се ползва (още от времето на Quake z-buffer-а...). Спокойно можеш да промениш и този на Paul да работи с повече променливи, понеже е wrapper проблема е само интерфейсен.
Стека? Това е memory manager и с стека си няма вземане-даване. Както казах - контейнерите да ходят в heap-a...

The ones who live by the sword get shot by the ones who don't.
Отговор
в отговор на Zemedelec #17

Re: Memory manager!

kato kazah steka - imah predvid che i steka ima nuzhda ot razni guardove :)

ne samo game industriata - mi wuobshte tam kudeto njama virtualna (logicheska) pamet - kudeto mozhe da se razkusa... dokolkoto znam starite Macove - njamaha takava - i trjabwashe da budesh mnogo vnimatelen kogato alokirash taka che da ne fragmentirash losho pametta...

Pochti ne se namirat weche PC-ta s takava pamet - no ima mnogo drugi dedicated platformi i ustrojstwa...

tirulirutatuutuu
Отговор