Помогите, плз, почему в первом случае памяти под строку выделено столько, сколько запрашивал, а в остальных случаях — нет?
Вместо new пробовал malloc, то же самое.
Компилил VC++ 6.0 SP4.
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv) //Использую: example HTTP://mshome.manser.net/Ch13/Login.asp
{
const int lenght = strlen(argv[1]);
char* tmp = new char[lenght];
strcpy(tmp, argv[1]);
printf("\n%d", lenght); //39
printf("\n%s", tmp); //39 символов, как и должно быть.int j = 0, k = 0, l = 0, m =0, n = 0;
for(j = 0; j < lenght; j++)
{
if(tmp[j] ==':')
{
k = j + 3;
break;
}
}
char* proto = new char[j];
const int lproto = strlen(proto);
printf("\n%d\n%d", j, lproto); //j=4, lproto=17, почему?
strncpy(proto, tmp,j);
printf("\n%s", proto); //17 символов.
n = k;
for(j = k; j < lenght; j++)
{
if(tmp[j] == '/')
{
l = j - n;
break;
}
continue;
}
char* hst = new char[l];
const int lhst = strlen(hst);
for(j = n ; j < (l + n); m++, j++)
{
hst[m] = tmp[j];
}
printf("\n%d\n%d", l, lhst); //l=17, lhst=33, почуму?
printf("\n%s", hst); //33 символа.
k = j;
for(j = k; j < lenght; j++)
{
tmp[j];
}
l = j - k;
char* dr = new char[l];
const int ldr = strlen(dr);
m = 0;
for(j = k; j < lenght; m++, j++)
{
dr[m] = tmp[j];
}
printf("\n%d\n%d", l, ldr); //l=15, ldr=33, почему?
printf("\n%s", dr); //33 символа.return 1;
}
On Wed, 07 Jan 2004 18:52:19 GMT, mansur <16299@news.rsdn.ru> wrote:
> Помогите, плз, почему в первом случае памяти под строку выделено столько, сколько запрашивал, а в остальных случаях — нет? > Вместо new пробовал malloc, то же самое. > Компилил VC++ 6.0 SP4.
> Код:
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> int main(int argc, char** argv) //Использую: example HTTP://mshome.manser.net/Ch13/Login.asp
> {
>
> const int lenght = strlen(argv[1]);
> char* tmp = new char[lenght];
// ^----потерял завершающий 0
// нужно new char[lenght + 1]
> strcpy(tmp, argv[1]);
> printf("\n%d", lenght); //39
> printf("\n%s", tmp); //39 символов, как и должно быть.
>
> int j = 0, k = 0, l = 0, m =0, n = 0;
>
> for(j = 0; j < lenght; j++)
> {
> if(tmp[j] ==':')
> {
> k = j + 3;
> break;
> }
> }
>
> char* proto = new char[j];
> const int lproto = strlen(proto);
// ^---- бессмысленно: proto - неинициализированная память
> printf("\n%d\n%d", j, lproto); //j=4, lproto=17, почему?
> strncpy(proto, tmp,j);
> printf("\n%s", proto); //17 символов.
// ^---- proto - строка из 4 символов без завершающего нуля
// ну и далее в таком духе
Пользуй std::string для строчек — не будет вышеперечисленных проблем. (но будут другие )
Исправил указанные ошибки, большое спасибо, но ничего не изменилось.
Кому не в тягость, скомпилите плз в 6-ой или 7-ой студии как пустой консольный проект,
и посмотрите вывод...
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int lenght = strlen(argv[1]);
char* tmp = new char[lenght +1]; //Исправил, ничего не изменилось.
strcpy(tmp, argv[1]);
printf("\n%d", lenght); //39
printf("\n%s", tmp); //39 символов, как и должно быть.
int j = 0, k = 0, l = 0, m =0, n = 0;
for(j = 0; j < lenght; j++)
{
if(tmp[j] ==':') //Количество символов протокола.
{
k = j + 3; //Пропускаем "://", до первого символа хоста.
break;
}
}
char* proto = new char[j]; //Буфер протокола
strncpy(proto, tmp,j);
const int lproto = strlen(proto);
printf("\n%d\n%d", j, lproto); //j=4, lproto=17, почему?
printf("\n%s", proto); //17 символов.
Здравствуйте, mansur, Вы писали:
M>Помогите, плз, почему в первом случае памяти под строку выделено столько, сколько запрашивал, а в остальных случаях — нет? M>Вместо new пробовал malloc, то же самое. M>Компилил VC++ 6.0 SP4.
По моему все дело в том что в первом случае строка копируется с символом конца строки
а в остальных случаях нет.
//j — до конца не доехало
char* proto = new char[j];
strncpy(proto, tmp,j);//скопировались сиволы до ":" и конец строки не установлен а за ним кусок пустой памяти.
//если его установить
proto[j]=0;
//то все должно быть нормально
const int lproto = strlen(proto);
printf("\n%d\n%d", j, lproto); //j=4, lproto=17
printf("\n%s", proto); //17
Здравствуйте, mansur, Вы писали:
M>Исправил указанные ошибки, большое спасибо, но ничего не изменилось. M>Кому не в тягость, скомпилите плз в 6-ой или 7-ой студии как пустой консольный проект, M>и посмотрите вывод... M>Код: M>#include <stdio.h> M>#include <stdlib.h> M>#include <string.h>
M>int main(int argc, char** argv) //Использую: example HTTP://mshome.manser.net/Ch13/Login.asp M>{
M> const int lenght = strlen(argv[1]); M> char* tmp = new char[lenght +1]; //Исправил, ничего не изменилось.
Зато теперь программа не будет падать или неправильно работать время от времени из-за того что пишет за пределы выделенной памяти.
strcpy всегда дописывает 0 символ в конце строки. strlen не считает этот ноль но он должен присутствовать как признак конца строки.
M> strcpy(tmp, argv[1]); M> printf("\n%d", lenght); //39 M> printf("\n%s", tmp); //39 символов, как и должно быть.
M> int j = 0, k = 0, l = 0, m =0, n = 0;
M> for(j = 0; j < lenght; j++) M> { M> if(tmp[j] ==':') //Количество символов протокола. M> { M> k = j + 3; //Пропускаем "://", до первого символа хоста.
хм, а правильность ввода (что после двоеточия всегда 2 слеша) не проверяется? ну ладно
да и, кто сказал что ':' не может быть последним символом? Ну вот, опять вылазим за пределы строки
M> break; M> } M> }
M> char* proto = new char[j+1]; //Буфер протокола M> strncpy(proto, tmp,j); proto[j] = 0; M> const int lproto = strlen(proto); M> printf("\n%d\n%d", j, lproto); //j=4, lproto=17, почему?
потому что нуль символа не было в конце строки. В первом случае где 39, повезло попасть на кусок памяти с нулем, в этом случае не повезло
M> printf("\n%s", proto); //17 символов.
M> n = k; //Запоминаем начало хоста.
M> for(j = k; j < lenght; j++) M> { M> if(tmp[j] == '/') M> { M> l = j — n; //Количество символов хоста. M> break; M> } M> continue; M> }
M> char* hst = new char[l+1]; //Буфер хоста.
M> for(j = n ; j < (l + n); m++, j++) M> { M> hst[m] = tmp[j]; //Копируем хост. M> } M> const int lhst = strlen(hst);
M> printf("\n%d\n%d", l, lhst); //l=17, lhst=33, почуму? M> printf("\n%s", hst); //33 символа.
M> k = j; //Запоминаем начало каталога.
M> for(j = k; j < lenght; j++) M> { M> tmp[j]; M> } M> l = j — k; //Количество символов каталога.
M> char* dr = new char[l]; //Буфер каталога. M> m = 0;
M> for(j = k; j < lenght; m++, j++) M> { M> dr[m] = tmp[j]; //Копируем каталог. M> } M> const int ldr = strlen(dr);
M> printf("\n%d\n%d", l, ldr); //l=15, ldr=33, почему? M> printf("\n%s", dr); //33 символа.
а где delete[] все те что выделены new[]?!!! меморилики
M> return 1; M>}
Диагноз: учиться работать со строками и памятью, и/или использовать std::string, CString & so on
А также нормально именовать переменные (от всех этих tmp, j, k, n, m голова кругом идет, ну почему бы им не называться nCharsProtocol, nCatalogIndex, nHostIndex к примеру.
И не мешало бы проверить argc перед доступом к argv, хотя если програмулина запускается автоматически с параметрами это не так важно но все же.
Здравствуйте, _Jane_, Вы писали:
_J_>Здравствуйте, mansur, Вы писали:
M>> const int lenght = strlen(argv[1]); M>> char* tmp = new char[lenght +1]; //Исправил, ничего не изменилось.
_J_>Зато теперь программа не будет падать или неправильно работать время от времени из-за того что пишет за пределы выделенной памяти. _J_>strcpy всегда дописывает 0 символ в конце строки. strlen не считает этот ноль но он должен присутствовать как признак конца строки.
M>> for(j = 0; j < lenght; j++) M>> { M>> if(tmp[j] ==':') //Количество символов протокола. M>> { M>> k = j + 3; //Пропускаем "://", до первого символа хоста.
_J_>хм, а правильность ввода (что после двоеточия всегда 2 слеша) не проверяется? ну ладно _J_>да и, кто сказал что ':' не может быть последним символом? Ну вот, опять вылазим за пределы строки
M>> break; M>> } M>> }
M>> char* proto = new char[j+1]; //Буфер протокола M>> strncpy(proto, tmp,j); _J_> proto[j] = 0; M>> const int lproto = strlen(proto); M>> printf("\n%d\n%d", j, lproto); //j=4, lproto=17, почему?
_J_>потому что нуль символа не было в конце строки. В первом случае где 39, повезло попасть на кусок памяти с нулем, в этом случае не повезло
_J_>а где delete[] все те что выделены new[]?!!! меморилики
_J_>Диагноз: учиться работать со строками и памятью, и/или использовать std::string, CString & so on _J_>А также нормально именовать переменные (от всех этих tmp, j, k, n, m голова кругом идет, ну почему бы им не называться nCharsProtocol, nCatalogIndex, nHostIndex к примеру. _J_>И не мешало бы проверить argc перед доступом к argv, хотя если програмулина запускается автоматически с параметрами это не так важно но все же.
Спасибо большое всем ответившим, всё исправил и заработало!
С уважением, Мансур М.Валиев.