Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамический массив помнит прошлые значения, В цикле c {new char (...) delete } 
V
    Опции темы
vitalyisaev2
Дата 27.2.2013, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 7.9.2010

Репутация: нет
Всего: нет



Уважаемые друзья, почему динамический массив  char * zeroBuffer после явного удаления себя в конце каждой итерации цикла и объявления заново сохраняет свои прошлые значения

(тот же * counterBuffer ведёт себя нормально - забывает себя в каждой итерации)? 

char * zeroBuffer  должен быть заполнен небольшим количеством нулей, но он дописывает к старому всё новые и новые нули, в результате переполняется стек (?)

Код

(...)
const char zero[] = "0";
(...)
for (int i = 1000; i < 100000; i+=1000)
    {
        char * zeroBuffer = new char[4]; //символьный массив, который должен быть заполнен символами "0"
                         //в количестве от 1 до 3, в зависимости от длины в цифрах числа i
        char * counterBuffer = new char[7]; //символьный массив - хранит значение i в символах
        (...)
                sprintf(counterBuffer, "%d", i);    
        iLength = strlen(counterBuffer);    
        for (int j = 0; j < (7 - iLength); j++) 
            zeroBuffer[j] = zero[0]; // первые несколько символов (не более (7 - iLength)) заполняются нулями 
        (...)
        delete[] zeroBuffer; //удаляем всё, чтобы в следующей итерации создать всё заново
        delete[] counterBuffer;
        (...)

    }




Вот что пишет отладчик:

Код

(gdb) display i
1: i = 1000
(gdb) display iLength
2: iLength = 4
(gdb) display zeroBuffer
3: zeroBuffer = 0x804c018 "000"

3: zeroBuffer = 0x804c038 "000\b000"
2: iLength = 4
1: i = 2000

3: zeroBuffer = 0x804c018 "000\b0002000"
2: iLength = 4
1: i = 3000


программа на этой итерации уже вылетает:
Код

*** glibc detected *** /home/vitalyisaev2/srcc/sen-venan-1d/file_handler/file_handler: malloc(): memory corruption (fast): 0x0804c048 ***

PM MAIL   Вверх
disputant
Дата 27.2.2013, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3



Что вы с ними (массивами) делаете еще?
Похоже, что память все же портится где-то в другом месте.

А что до "помнит себя" - так оператор new вроде бы память не обнуляет, так что если выделится тот же кусок памяти - вот и "запоминание"...
PM MAIL   Вверх
vitalyisaev2
Дата 27.2.2013, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 7.9.2010

Репутация: нет
Всего: нет



Вся работа с памятью, которая вызывает проблемы, происходит внутри большого цикла for (int i = 1000; i < 100000; i+=1000)

Код

#include <iostream>
#include <string.h>
#include <fstream>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

void process_file (char *folderCh, char *nameCh)
{ 
        //Change directory if necesary
        if (chdir(folderCh) == 0) cout << "Resulting file will be put into specified directory: " << folderCh << endl;
                else cout << "Resulting file will be put into current directory: ./" << endl;
        
        //Specify input files
        int underscores, inFileNameLength, iLength; //Number of gaps in filenames 
        const int timeLine = 7; //Symbols for time in filenames
        const char exeptVariableType[] = "Discharge", extension[] = ".txt", underscore[] = "_", zero[] = "0";
        if (strcmp(nameCh,exeptVariableType) == 0) underscores = 6;
                else underscores = 9;
        inFileNameLength = sizeof(nameCh)+underscores+timeLine+sizeof(extension)+1; //Length of filenames 
        char * inFileUnderscores = new char[underscores+1]; // Array for gaps in filenames
        for (int i = 0; i < underscores; i++) strcat(inFileUnderscores, underscore);
        for (int i = 1000; i < 100000; i+=1000)
        {
                char * zeroBuffer = new char[4]; //for the first "000"
                char * counterBuffer = new char[7]; //for the iterated time 
                char * timeBuffer = new char[8]; //for the whole end of the every filename
                sprintf(counterBuffer, "%d", i);
                iLength = strlen(counterBuffer);
                for (int j = 0; j < (7 - iLength); j++) 
                        zeroBuffer[j] = zero[0];
                strcat(strcpy(timeBuffer,zeroBuffer),counterBuffer);//time-defined end of filename captured in char * timeBuffer)
                char * inFileName = new char[inFileNameLength]; //for the whole filename
                strcat(strcpy(inFileName, nameCh),inFileUnderscores);
                strcat(inFileName,timeBuffer); 
                strcat(inFileName,extension);//filename captured in char * inFileName
                cout << inFileName << endl;
                delete[] zeroBuffer; //free memory
                delete[] counterBuffer;
                delete[] timeBuffer;
                delete[] inFileName;
        }
        delete inFileUnderscores;
        
        //Specify output file
        char * outFileName = new char[sizeof(extension) + sizeof(nameCh)+1];
        strcat(strcpy(outFileName, nameCh), extension);
        ofstream outFile(outFileName);
        outFile.close();
        delete outFileName;
}

int main(int argc, char *argv[]) 
{
        const char type1[] = "Discharge", type2[] = "Scross", type3[] = "uspeed", type4[] = "hriver";     
        if ((strcmp(argv[2],type1) == 0) || (strcmp(argv[2],type2) == 0) || 
                        (strcmp(argv[2],type3) == 0) || (strcmp(argv[2],type4) == 0)) 
                                process_file(argv[1], argv[2]);
                else cout << "wrong parameter" << endl;
        return 0;
}

PM MAIL   Вверх
feodorv
Дата 28.2.2013, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(vitalyisaev2 @  27.2.2013,  20:26 Найти цитируемый пост)
вылетает

В принципе, должна вылететь. Посмотрите сюда:
Цитата(vitalyisaev2 @  27.2.2013,  22:27 Найти цитируемый пост)
       inFileNameLength = sizeof(nameCh)+underscores+timeLine+sizeof(extension)+1; //Length of filenames 
        char * inFileUnderscores = new char[underscores+1]; // Array for gaps in filenames
        for (int i = 0; i < underscores; i++) strcat(inFileUnderscores, underscore);
  • sizeof(nameCh) считать бесполезно, даст всегда 4 (или 8 в 64-битном окружении), наверное, нужно strlen(nameCh)
  • strcat(inFileUnderscores,...) подразумевает, что inFileUnderscores завершён нулём. Не уверен, что new обнуляет заказанную память.
Посмотрите сюда:
Цитата(vitalyisaev2 @  27.2.2013,  22:27 Найти цитируемый пост)
                for (int j = 0; j < (7 - iLength); j++) 
                        zeroBuffer[j] = zero[0];
                strcat(strcpy(timeBuffer,zeroBuffer),counterBuffer);//time-defined end of filename captured in char * timeBuffer)
                char * inFileName = new char[inFileNameLength]; //for the whole filename
                strcat(strcpy(inFileName, nameCh),inFileUnderscores);

Тоже самое, используется strcat, а массивы не завершены нулями.

В конце концов, Вы используете C++, так для строк используйте std::string, ошибки с завершающим нулём уйдут. Правда, могут появиться другие)))

Если же Вам так милы C-style strings, то Вы обязаны хранить в конце строки символ '\0', не говоря о том, что под него тоже нужно резервировать память. Память-то у Вас, вроде, под '\0' резервируется, а вот '\0' нигде не участвует, например:
Цитата(vitalyisaev2 @  27.2.2013,  22:27 Найти цитируемый пост)
        char * inFileUnderscores = new char[underscores+1]; // Array for gaps in filenames
        inFileUnderscores[0] = '\0';
        for (int i = 0; i < underscores; i++) strcat(inFileUnderscores, underscore);


Цитата(vitalyisaev2 @  27.2.2013,  22:27 Найти цитируемый пост)
               for (int j = 0; j < (7 - iLength); j++) 
                        zeroBuffer[j] = zero[0];
                zeroBuffer[j] = '\0';
                strcat(strcpy(timeBuffer,zeroBuffer),counterBuffer);//time-defined end of filename captured in char * timeBuffer)


Хотя, конечно, код ещё пилить и пилить. Отказывайтесь Вы от этих бесконечных strcat и strcpy...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Dem_max
Дата 1.3.2013, 07:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Цитата

        for (int j = 0; j < (7 - iLength); j++) 
            zeroBuffer[j] = zero[0]; // первые несколько символов (не более (7 - iLength)) заполняются нулями 

Я думаю тут с большой вероятностью будет возникать выход за границы массива.


А если честно весь код мутно не понятный и неизвестно что пытается сделать.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
feodorv
Дата 1.3.2013, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(Dem_max @  1.3.2013,  08:03 Найти цитируемый пост)
Я думаю тут с большой вероятностью будет возникать выход за границы массива.

Dem_max, не будет. iLength начинается с 4, поэтому в zeroBuffer место ещё и останется на '\0'.

Цитата(Dem_max @  1.3.2013,  08:03 Найти цитируемый пост)
А если честно весь код мутно не понятный и неизвестно что пытается сделать. 

Код генерирует последовательность файловых имён вида
Код

sprintf( inFileName, "%s%s%07d.txt", nameCh, (underscores == 9) ? "_________" : "______", i);



Это сообщение отредактировал(а) feodorv - 1.3.2013, 20:40


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
vitalyisaev2
Дата 1.3.2013, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 7.9.2010

Репутация: нет
Всего: нет



Всем огромное спасибо за замечания.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0534 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.