информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяГде водятся OGRыАтака на Internet
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
я тоже раньше так думал 05.05.08 14:54  Число просмотров: 2900
Автор: dl <Dmitry Leonov>
Отредактировано 05.05.08 15:47  Количество правок: 5
<"чистая" ссылка>
> В целом абсолютно согласен, но небольшое замечание сделаю
> > buf1= new char [10000000];
> > delete buf1; - учите язык
> Абсолютно корректно (ну зачем нам деструкторы char-а?).
> Более того, в неявном виде я и сам такую запись использую
> постоянно:
> std::auto_ptr<char> buf(new char[SIZE]);

Хотя в первых книжках Страуструпа и можно прочитать, что delete [] отличается от delete вызовом деструктора для каждого элемента массива (так вел себя cfront), согласно стандарту, поведение delete для памяти, выделенной new[], не определено и вполне может привести к непредсказуемым результатам вплоть до heap corruption - даже для простых типов. Конкретные реализации типа Visual C++ это дело могут прощать (реально все зависит от того, как организовано хранение информации о размере массива), но в общем случае на это лучше не закладываться.

> Просто потому, что векторного auto_ptr-а нет. Другое дело,

Ну есть же shared_ptr/shared_array из boost. Auto_ptr - это вообще хождение по минному полю.

http://www.new-brunswick.net/workshop/c++/faq/freestore-mgmt.html#faq-16.12
http://www.new-brunswick.net/workshop/c++/faq/compiler-dependencies.html#faq-38.7
<programming>
отправляется запрос веб серверу, клиент от него получает 1 файл и виснет 26.04.08 03:44  
Автор: saynsk2 Статус: Незарегистрированный пользователь
<"чистая" ссылка>
отправляется запрос веб серверу, клиент от него получает 1 файл и виснет.
В чем может быть проблема?
код следущий:

//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#include <windowsx.h>
#include <winsock2.h>
#pragma comment( lib, "Ws2_32.lib" )
#include <stdlib.h>
#pragma hdrstop
#include "Unit2.h"
#include "Unit3.h"
#include "Unit1.h"
#define OUT_IP "127.0.0.1"
#pragma package(smart_init)
#pragma resource "*.dfm"
#define IN_PORT 60
TForm1 *Form1;
int gha;
qwe *we[50];
int e;
int s=0;
int kk;
SOCKET u;
int qaz;
SOCKET ds[24];
HANDLE ThreadInfo[24];
int rt=0;
int rr=0;
char ssc[]=" HTTP/1.1\r\n"
"User-Agent: Opera/9.00 (Windows NT 5.1; U; en)\r\n"
"Host: 127.0.0.1:60\r\n"
"Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n"
"Accept-Language: ru,en;q=0.9\r\n"
"Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n"
"Connection: Keep-Alive\r\n\r\n";
//---------------------------------------------------------
char dfg1[]="HTTP/1.1 200 OK\n"
"Content-Length: 1600\n"
"Content-Type: text/html\n"
"\n"
"\n"
"<html>"
"<head>"
"<title>Untitled Document</title>"
"<meta http-equiv='Content-Type' content='text/html' charset='windows-1251'>"
"</head>"
"<frameset rows='30%,70%'>"
"<frame name='q1' src='pizdce'>"
"<frame name='q2' src='popm'>"
"</html>";
char dfg[]="HTTP/1.1 200 OK\n"
"Content-Length: 60\n"
"Content-Type: text/html\n"
"\n"
"\n"
"<script>"
"var d=0;"
"function show()"
"{d=d+1;"
"if (d<2)"
"{"
"self.parent.frames.q2.location='http://127.0.0.1:60/popu";
char dfgt[]="';}"
"setTimeout('show()',1);"
"}"
"</script>"
"<html>"
"<head>"
"<title>Untitled Documen</title>"
"<meta http-equiv='Content-Type' content='text/html' charset='windows-1251'>"
"</head>"
"<body onLoad='show()'>"
"<form name='form1' method='get' action='w'>"
"<input type='text' name='rfzda'>"
"<input type='submit' name='Submit' value='Submit'>"
"</form>"
"</body>"
"</html>";
//--------------------------------------------------------------------
DWORD WINAPI CountThread(LPVOID arg)
{
struct sockaddr_in ssin;
struct hostent* hp;
int rr,rt2;
int ery;
int kl=0;
char *buf1;
int i;
SOCKET s1;
int k1=0;
int yy=0;
int jk=0;
int df=0;
int azx=0;
int fff=0;
char sdd[]="&pk=http";
int ss=0;
int ffs=0;
int kl1=0;
int bnh=0;
char bufg1 [300];
char buf2 [1000];
//AnsiString g="ÏÎØÅË ";
//g=g+AnsiString(rt++);
rr=rt;
SOCKET su;
char *buf;
char *buf3;
//g:
//if (s==1) goto y;
//goto g;
//y:
//AnsiString g="potok N"+AnsiString(rr);
char bufg [100];
jjk:
if (s!=1) goto jjk;
buf1= new char [10000000];
buf3= new char [10000000];
buf= new char [10000000];
//s=0;
su=ds[qaz];
//asw="ss"+AnsiString(s);
qaz++;
int r=recv(su,buf,1000,0);
if (r==SOCKET_ERROR)
{
Form1->Memo1->Lines->Add("recv");
delete buf1;
delete buf3;
delete buf;
closesocket(su);
qaz--;
s=0;
goto jjk;
return 0;
}
Form1->Memo1->Lines->Add(AnsiString("razmer buf:")+r);
Form1->Memo1->Lines->Add(AnsiString(buf));
for (i=0;i<1000;i++)
{
if (buf[i]==' ' && jk==0)
{
jk=1;
kl1=i+2;
}
//-------------------------------------------------------------------
if (fff==1)
if (buf[i+1]!='&')
{
if (buf[i+1]=='h' && buf[i+2]=='t' && buf[i+3]=='t' && buf[i+4]=='p')
{
yy=1;
i=i+13;
}
if (buf[i+1]=='%' && buf[i+2]=='2' && buf[i+3]=='F')
{
bufg1[bnh++]='/';
i=i+2;
}
else
bufg1[bnh++]=buf[i+1];
}
else
{
bufg1[bnh]='\0';
fff=0;
strcpy(buf2,dfg);
strcat (buf2,bufg1);
if (yy==1) strcat (buf2,sdd);
strcat (buf2,dfgt);
int hh=sizeof(dfg)+sizeof(dfgt)+bnh;
bnh=0;
//if (yy==1) hh=hh+sizeof(sdd);
send(su,buf2,hh,0);
closesocket(su);
qaz--;
Form1->Memo1->Lines->Add(AnsiString("1111111111111111111111111111111111"));
s=0;
delete buf1;
delete buf3;
delete buf;
goto jjk;
return 0;
}
//--------------------------------------------
if (buf[i-4]=='r' && buf[i-3]=='f' && buf[i-2]=='z' && buf[i-1]=='d' && buf[i]=='a')
{
Form1->Memo1->Lines->Add(AnsiString("rfzda"));
fff=1;
}
//--------------------------------------------
if (buf[i]=='p' && buf[i+1]=='i' && buf[i+2]=='z' && buf[i+3]=='d' && buf[i+4]=='c' && buf[i+5]=='e')
{
Form1->Memo1->Lines->Add(AnsiString("pizdce"));
char df[]="127.0.0.1/g/yot.asp";
strcpy (buf2,dfg);
strcat (buf2,df);
strcat (buf2,dfgt);
int hh=sizeof(dfg)+sizeof(df)+sizeof(dfgt);
Form1->Memo1->Lines->Add(AnsiString(buf2));
send(su,buf2,hh,0);
closesocket(su);
qaz--;
Form1->Memo1->Lines->Add(AnsiString("333333333333333333333333333333"));
s=0;
delete buf1;
delete buf3;
delete buf;
goto jjk;
return 0;
}
//--------------------------------------------------------------
if (ffs==1)
{
//Form1->Memo1->Lines->Add(AnsiString("ffs"));
if (buf[i]!='&')
{
if (buf[i]=='/') azx=1;
if (azx==1)
buf1[bnh++]=buf[i];
}
else
{
buf1[bnh]='\0';
bnh=0;
//delete buf;
//buf= new char [10000000];
char ddw[]="GET ";
strcpy(buf,ddw);
strcat(buf,buf1);
Form1->Memo1->Lines->Add(AnsiString(buf1));
strcat(buf,ssc);
ffs=0;
goto dd;
}}
//--------------------------------------------------------------
if (buf[i]=='p' && buf[i+1]=='o' && buf[i+2]=='p' && buf[i+3]=='m')
{
azx=0;
bnh=0;
Form1->Memo1->Lines->Add(AnsiString("popm"));
closesocket(su);
Form1->Memo1->Lines->Add(AnsiString("444444444444444444444444444444444"));
qaz--;
s=0;
delete buf1;
delete buf;
delete buf3;
goto jjk;
return 0;
}
//--------------------------------------------------------------
if (buf[i]=='p' && buf[i+1]=='o' && buf[i+2]=='p' && buf[i+3]=='u')
{
Form1->Memo1->Lines->Add(AnsiString("popu"));
/*
azx=0;
bnh=0;
Form1->Memo1->Lines->Add(AnsiString("popm"));
closesocket(su);
Form1->Memo1->Lines->Add(AnsiString("444444444444444444444444444444444"));
qaz--;
delete buf1;
delete buf;
delete buf3;
return 0;
*/
ffs=1;
}
//--------------------------------------------------------------
if (kl==0)
bufg[i-kl1]=buf[i-1];
if (buf[i]=='H' && buf[i+1]=='T' && buf[i+2]=='T')
{
bufg[i-kl1]='\0';
rr=i-kl1;
kl=1;
}
}
buf[r]='\0';
if (bufg[0]=='/' && rr==1)
{
//Form1->Memo1->Lines->Add(AnsiString(bufg));
//Form1->Memo1->Lines->Add(AnsiString(buf));
send(su,dfg1,sizeof(dfg1),0);
closesocket(su);
Form1->Memo1->Lines->Add(AnsiString("5555555555555555555555555555555555"));
qaz--;
s=0;
delete buf1;
delete buf3;
delete buf;
goto jjk;
return 0;
}
dd:
//Form1->Memo1->Lines->Add(r);
Form1->Memo1->Lines->Add(AnsiString(buf));
int j;
fff=0;
int PortNum = 80;
ssin.sin_family = AF_INET;
ssin.sin_addr.s_addr = inet_addr(OUT_IP);
ssin.sin_port = htons(PortNum);
if((s1=socket(AF_INET, SOCK_STREAM, 0))==-1)
Form1->Memo1->Lines->Add(AnsiString("SOCKET"));
if(connect(s1,(PSOCKADDR)&ssin, sizeof(ssin))==-1)
Form1->Memo1->Lines->Add(AnsiString("CONNECT"));
send(s1,buf,r,0);
Form1->Memo1->Lines->Add("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
Form1->Memo1->Lines->Add(AnsiString(s1));
WSABUF in;
//WSAOVERLAPPED async;
WSABUF wbuf;
DWORD dwBytesRecv,dwFlags;
wbuf.buf = buf3;
wbuf.len = 1000;
dwFlags = 0;
//причина здесь
//----------------------------------------------------------------
int ret = WSARecv(s1, &wbuf, 1, &dwBytesRecv,&dwFlags, NULL, NULL);
//r=recv(s1,buf3,10000000000000,0);
//----------------------------------------------------------------
Form1->Memo1->Lines->Add("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
int yhy;
if (r==SOCKET_ERROR)
{
Form1->Memo1->Lines->Add("recv1");
yhy=WSAGetLastError();
}
//Form1->Memo1->Lines->Add(AnsiString("prinytoe ot servera:"));
if (yhy==WSANOTINITIALISED) Form1->Memo1->Lines->Add("WSANOTINITIALISED");
if (yhy==WSAENETDOWN) Form1->Memo1->Lines->Add("WSAENETDOWN");
if (yhy==WSAENOTCONN) Form1->Memo1->Lines->Add("WSAENOTCONN");
if (yhy==WSAEINTR)Form1->Memo1->Lines->Add("WSAEINTR");
if (yhy==WSAEINPROGRESS)Form1->Memo1->Lines->Add("WSAEINPROGRESS");
if (yhy==WSAENOTSOCK)Form1->Memo1->Lines->Add("WSAENOTSOCK");
if (yhy==WSAESHUTDOWN) Form1->Memo1->Lines->Add("WSAESHUTDOWN");
if (yhy==WSAEWOULDBLOCK) Form1->Memo1->Lines->Add("WSAEWOULDBLOCK");
if (yhy==WSAEMSGSIZE) Form1->Memo1->Lines->Add("WSAEMSGSIZE");
if (yhy==WSAEINVAL) Form1->Memo1->Lines->Add("WSAEINVAL");
if (yhy==WSAECONNABORTED) Form1->Memo1->Lines->Add("WSAECONNABORTED");
if (yhy==WSAECONNRESET) Form1->Memo1->Lines->Add("WSAECONNRESET");
Form1->Memo1->Lines->Add(AnsiString(yhy));
Form1->Memo1->Lines->Add(AnsiString(buf3));
for (i=0;i<1000;i++)
{
if (buf3[i]=='L' && buf3[i+1]=='e' && buf3[i+2]=='n' && buf3[i+3]=='g' && buf3[i+4]=='t' && buf3[i+5]=='h')
for (j=0;j<9;j++)
{
buf2[j]=buf3[i+j+8];
if (buf2[j]=='\n')
{
buf2[j]=='\0';
goto h;
}}
//-----------------------------------------------------
h:
if (buf3[i]=='\n' && buf3[i+2]=='\n')
{
ery=i+1;
//ss=1;
goto ff;
}
/*
if (ss==1)
{
if (buf3[i-5]=='h' && buf3[i-4]=='t' && buf3[i-3]=='t' && buf3[i-2]=='p' && buf3[i-1]==':' && buf3[i]=='/')
{
fff=1;
char hhj[]="http://127.0.0.1/pivo=";
strcat(buf1,hhj);
bnh=bnh+22;
}
if (fff==1)
if (buf3[i+1]!='"')
buf[df++]=buf3[i+1];
else
{
buf[df]='\0';
bnh=bnh+df;
df=0;
fff=0;
strcat(buf1,buf);
}}
buf1[bnh++]=buf3[i];
*/
}
ff:
int d=atoi(buf2);
strcpy(buf1,buf3);
int k=d;
fff=0;
k=k+ery-r;
//int s=0;
int eee=r;
AnsiString hju;
if (d>1000)
{
nn:
Form1->Memo1->Lines->Add("d>1000");
r=recv(s1,buf3,k,0);
hju="r"+AnsiString(r);
Form1->Memo1->Lines->Add(hju);
if (r==0) goto aaa;
if (r!=SOCKET_ERROR)
{
eee=r+eee;
k=k-r;
strcat (buf1,buf3);
//s++;
hju="k"+AnsiString(k);
Form1->Memo1->Lines->Add(hju);
goto nn;
}else
Form1->Memo1->Lines->Add("error");
}
aaa:
hju="s"+AnsiString(s);
Form1->Memo1->Lines->Add(AnsiString(s));
Form1->Memo1->Lines->Add("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
Form1->Memo1->Lines->Add(AnsiString(buf1));
//Form1->Memo1->Lines->Add(r);
//r=recv(s1,buf3,100000000000000000,0);
//k1=k1-r;
//if (k1>0 | k1!=0) goto ggg;
//Form1->Memo1->Lines->Add(AnsiString(buf1));
//Form1->Memo1->Lines->Add("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
//Form1->Memo1->Lines->Add("");
//Form1->Memo1->Lines->Add(AnsiString(buf1));
/*
for (i=0;i<k1;i++)
{
//int gg=r-i;
//Form1->Memo1->Lines->Add(gg);
if (buf3[i-5]=='h' && buf3[i-4]=='t' && buf3[i-3]=='t' && buf3[i-2]=='p' && buf3[i-1]==':' && buf3[i]=='/')
{
fff=1;
char hhj[]="http://127.0.0.1/pivo=";
strcat(buf1,hhj);
bnh=bnh+22;
}
if (fff==1)
if (buf3[i+1]!='"')
buf[df++]=buf3[i+1];
else
{
buf[df]='\0';
bnh=bnh+df;
df=0;
fff=0;
strcat(buf1,buf);
}
buf1[bnh++]=buf3[i];
}
*/
//buf1[bnh]='\0';
//bnh=bnh+1000000;
//int rre=send(su,buf1,bnh,0);
//Form1->Memo1->Lines->Add(AnsiString(bnh));
//Form1->Memo1->Lines->Add(AnsiString(rre));
//Form1->Memo1->Lines->Add("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
//Form1->Memo1->Lines->Add(AnsiString(buf1));
//Form1->Memo1->Lines->Add(k);
//Form1->Memo1->Lines->Add(rre);
send(su,buf1,eee,0);
closesocket(su);
shutdown(s1,2);
closesocket (s1);
qaz--;
Form1->Memo1->Lines->Add(AnsiString("6666666666666666666666666666666666"));
delete buf1;
delete buf3;
delete buf;
s=0;
kk++;
goto jjk;
//CloseHandle(GetCurrentThread());
return 0;
}
//--------------------------------------------------------------
DWORD WINAPI CountThrea(LPVOID arg)
{
DWORD dwThreadID;
sockaddr addr1;
WSADATA stWSADataTCPIP;
char buf[100000];
WSAStartup(0x0101, &stWSADataTCPIP);
int hListenSockTCP = socket (AF_INET,SOCK_STREAM,0);
if (hListenSockTCP==0) Form1->Memo1->Lines->Add("ERROR socket");
SOCKADDR_IN myaddrTCP;
myaddrTCP.sin_family = AF_INET;
myaddrTCP.sin_addr.s_addr = htonl (INADDR_ANY);
myaddrTCP.sin_port = htons (IN_PORT);
int r=bind( hListenSockTCP,(LPSOCKADDR)&myaddrTCP, sizeof(struct sockaddr));
if (r==0) Form1->Memo1->Lines->Add("bind");
r=listen (hListenSockTCP, SOMAXCONN);
if (r==0) Form1->Memo1->Lines->Add("listen");
int j=sizeof(struct sockaddr);
bb:
if (s==0)
{
u=accept (hListenSockTCP,&addr1,&j);
if (u!=INVALID_SOCKET)
{
qaz=0;
Form1->Memo1->Lines->Add("accept");
ds[qaz]=u;
AnsiString gg="tt"+AnsiString(s);
Form1->Memo1->Lines->Add(gg);
s=1;
//ThreadInfo[qaz] = CreateThread (NULL,0,&CountThread,NULL,0,&dwThreadID);
//SetThreadPriority(ThreadInfo[qaz],THREAD_PRIORITY_BELOW_NORMAL);
}
else
Form1->Memo1->Lines->Add("accept error");
}
goto bb;
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
kk=0;
DWORD dwThreadID;
HANDLE ThreadInfo;
HANDLE ThreadInfo1;
gha=1;
qaz=0;
ThreadInfo = CreateThread (NULL,0,&CountThrea,NULL,0,&dwThreadID);
SetThreadPriority(ThreadInfo, THREAD_PRIORITY_BELOW_NORMAL);
ThreadInfo1 = CreateThread (NULL,0,&CountThread,NULL,0,&dwThreadID);
SetThreadPriority(ThreadInfo1,THREAD_PRIORITY_BELOW_NORMAL);
}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
WSACleanup ();
}
//---------------------------------------------------------------------------
Не пробовал сперва через отладчик прогнать? 26.04.08 14:30  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
[C++] а без отладчика никак? 27.04.08 02:24  
Автор: saynsk2 Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Проблемма в стиле написания: 05.05.08 12:51  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка>
Проблемма в стиле написания:

int j; - не инициализированная переменная

fff=0; - невнятное имя переменной

goto jjk; - нецензурное выражение

buf1= new char [10000000];
delete buf1; - учите язык

Структура программы отсутствует как класс.

Итак по всему коду. Было бы удивительно, если бы все это работало :))
И не лень тебе было? :)) 05.05.08 14:51  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
Ремарка 05.05.08 13:03  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
В целом абсолютно согласен, но небольшое замечание сделаю

> buf1= new char [10000000];
> delete buf1; - учите язык

Абсолютно корректно (ну зачем нам деструкторы char-а?). Более того, в неявном виде я и сам такую запись использую постоянно:
std::auto_ptr<char> buf(new char[SIZE]);

Просто потому, что векторного auto_ptr-а нет. Другое дело, что скорее всего просто не знает отличий между скалярным и векторным delete и сделал свой выбор не осознанно (как в вышеприведенном примере), а по незнанию.

Собственно на том же месте другая грубейшая ошибка, которая в данном конкретном случае не приводит ни к чему фатальному

buf1= new char [10000000]; 
buf3= new char [10000000]; 
buf= new char [10000000];
//..............
delete buf1; 
delete buf3; 
delete buf;
//............
delete buf1; 
delete buf; 
delete buf3;

---

Порядок освобождения ресурсов не просто не обратный - а как бог на душу положит.

Полный разбор делать естественно не буду потому, что на код страшно смотреть - не то, что ковырять

> Структура программы отсутствует как класс.
>
> Итак по всему коду. Было бы удивительно, если бы все это
> работало :))
я тоже раньше так думал 05.05.08 14:54  
Автор: dl <Dmitry Leonov>
Отредактировано 05.05.08 15:47  Количество правок: 5
<"чистая" ссылка>
> В целом абсолютно согласен, но небольшое замечание сделаю
> > buf1= new char [10000000];
> > delete buf1; - учите язык
> Абсолютно корректно (ну зачем нам деструкторы char-а?).
> Более того, в неявном виде я и сам такую запись использую
> постоянно:
> std::auto_ptr<char> buf(new char[SIZE]);

Хотя в первых книжках Страуструпа и можно прочитать, что delete [] отличается от delete вызовом деструктора для каждого элемента массива (так вел себя cfront), согласно стандарту, поведение delete для памяти, выделенной new[], не определено и вполне может привести к непредсказуемым результатам вплоть до heap corruption - даже для простых типов. Конкретные реализации типа Visual C++ это дело могут прощать (реально все зависит от того, как организовано хранение информации о размере массива), но в общем случае на это лучше не закладываться.

> Просто потому, что векторного auto_ptr-а нет. Другое дело,

Ну есть же shared_ptr/shared_array из boost. Auto_ptr - это вообще хождение по минному полю.

http://www.new-brunswick.net/workshop/c++/faq/freestore-mgmt.html#faq-16.12
http://www.new-brunswick.net/workshop/c++/faq/compiler-dependencies.html#faq-38.7
О. Ну да, как миниум VC с этим отлично работает 05.05.08 16:09  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Хотя в первых книжках Страуструпа и можно прочитать, что
> delete [] отличается от delete вызовом деструктора для
> каждого элемента массива (так вел себя cfront), согласно
> стандарту, поведение delete для памяти, выделенной new[],
> не определено и вполне может привести к непредсказуемым
> результатам вплоть до heap corruption - даже для простых
> типов. Конкретные реализации типа Visual C++ это дело могут
> прощать (реально все зависит от того, как организовано
> хранение информации о размере массива), но в общем случае
> на это лучше не закладываться.

Как то у меня даже мысли не было, что хип может не хранить размер выделенного куска памяти. Собственно именно из-за того, что даже C хранит размеры всех без исключения блоков динамической памяти (для того чтобы работал realloc к примеру) мне даже в голову не приходило, что блок памяти может выделиться без заголовка, ведь как минимум надо ж знать об этой памяти всякую информацию для того, чтобы ее потом освободить. Сейчас подумал и понял, что действительно хип можно реализовать как нибудь настолько убого, что это будет приводить к вышеописанным эффектам, но на самом деле надо будет поковыряться на досуге в стандарте - не зря ж стауструп говорит о деструкторах.

> > Просто потому, что векторного auto_ptr-а нет. Другое
> дело,
>
> Ну есть же shared_ptr/shared_array из boost. Auto_ptr - это
> вообще хождение по минному полю.

Да я его кроме хранения буферов памяти нигде и не использую. При работе с объектами мне больше нравятся intrusive_ptr-ы. Кстати, они уже не в бусте а в C++ TR1 (последний feature pack для VS2008 в числе прочего содержит и эти указатели).
по второй ссылке из предыдущего поста это описано 05.05.08 16:25  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
> будет приводить к вышеописанным эффектам, но на самом деле
> надо будет поковыряться на досуге в стандарте - не зря ж
> стауструп говорит о деструкторах.

Он об этом говорил, когда основной (если не единственной реализацией) была cfront'овская. Потом ради эффективности сделали вариант с over-allocation.
Не нашел в стандарте вообще ничего про скалярный delete, вызванный для вектора (в смысле массива, а не std::vector) 05.05.08 17:23  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
Значит на усмотрение реализации, что в свою очередь значит - может случиться вообще все что угодно.

> Он об этом говорил, когда основной (если не единственной
> реализацией) была cfront'овская. Потом ради эффективности
> сделали вариант с over-allocation.

В любом случае спасибо за информацию. Прекращать так делать пока не буду, потому как портирование на другие компиляторы/платформы пока не предвидится, но по крайней мере буду знать откуда ждать проблем.
То есть кто-то должен отладить программу за тебя? :))) 28.04.08 18:04  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach