Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
 Аватар для 1nquisitor
4 / 4 / 1
Регистрация: 24.02.2014
Сообщений: 102

Переполнение массива

21.06.2015, 10:23. Показов 2457. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Товарищи, имею такой вопрос- есть у меня часть кода, которая отвечает за загрузку из интерне xml файла и созраняющая его в массив. Все работает, но только во время первого цикла вызова функции internet(), во время вызова этой функции повторно- массив, содержащий значения, которые он получил циклом ранее переполняется. Пробовал освобождать его memsetом- но данные норовят записаться в конец массива- те выглядит это так
1 пустой массив []
2 забил данными ["бла бла бла"]
3 освободил мемсетом [ ]
4 записал новые данные [ "бла бла бла"]

что я делаю не так?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "stdafx.h"
#include <stdio.h>
#include <locale.h>
#include "curl/curl.h"
#include "Data.h"
#include "AllDataSaver.h"
#include "COM.h"
 
#pragma comment(lib,"curllib.lib")    
//--------------------------------------------------------------------------
 
const size_t BUF_SIZE= 800;
char   wr_buf[BUF_SIZE+1];  
char*   wr_buf[BUF_SIZE+1];
char TempBuf[7];
size_t  wr_index=0;
 
//---------------------------------------------------------------------------
void internet()
{
 
    setlocale(0,"rus");
    CURL *curl_handle;
    CURLcode res;
    
    curl_handle = curl_easy_init();
 
 
    if(curl_handle)
        {
            curl_easy_setopt(curl_handle, CURLOPT_URL, "http://api.openweathermap.org/data/2.5/weather?q=Dresden&mode=xml");
 
            curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, wr_buf);
            curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
 
            CURLcode res = curl_easy_perform(curl_handle);
 
            if(res == CURLE_OK)
              {
                  
               printf("%s", wr_buf); // выводим буфер в консоль.
                
               data("temperature value=\"",6,1);
                
                 }
            else 
            printf( "curl_easy_perform() failed: %s\n", curl_easy_strerror(res) );
                       
        }
 
    curl_easy_cleanup(curl_handle);
    
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.06.2015, 10:23
Ответы с готовыми решениями:

Переполнение массива
Добрый день господа. :) Столкнулся с очередной проблемой и не знаю как решить. Где то в этой программе происходит переполнение...

Снова про переполнение массива
#include &lt;iostream&gt; using namespace std; int main () { char ar; cin &gt;&gt; ar; cout &lt;&lt; ar; return 0; ...

Исключительная ситуация (переполнение массива сверху)
Изучаем сейчас исключительные ситуации и нужно привести пример , т.е. вызвать исключительную ситуацию для переполнения массива сверху или...

5
19 / 19 / 6
Регистрация: 21.06.2015
Сообщений: 34
21.06.2015, 10:38
Исходники не полные, нет функции write_data, в которой видимо и проблема, без этого ответить на вопрос по-моему не представляется возможным, поэтому даю общие рекомендации.

1. Уже есть C++, в котором есть безопасные массивы std::vector - используя их, проблем с памятью будет существенно меньше. С CURL все прекрасно совместимо (говорю по собственному опыту).
По быстродействию и эффективности они столь же эффективны, как и обычные массивы.

2. Не все, особенно новички, знают, что можно ставить breakpoint не на код, а на память приложения. Выглядит это примерно так:
- Тормозим программу в начале ее исполнения обычным breakpointом
- Ставим breakpoint на память, для Visual Studio - Debug\New Breakpoint\ New Data Breakpoint...
в адрес задаем проблемный адрес - в твоем случае это адрес конца массива &(wr_buf[BUF_SIZE-4])
- Что это дает? Что это за брейкпоинт?
Этот брейкпоинт сработает когда в указанный адрес будет производится запись.
Таким образом ты увидишь какой именно строкой кода проводится изменения той памяти, которую ты хочешь оставить неизменной.
0
 Аватар для 1nquisitor
4 / 4 / 1
Регистрация: 24.02.2014
Сообщений: 102
21.06.2015, 11:03  [ТС]
вот полный код- просто не хотел засорять "эфир". Я про векторы тоже подумал, но уже слишком поздно, так как все остальные мои функции и методы работают именно на обычных массивах- а переделывать значит, просто переписать почти весь код, что является крайне печальным, особенно на финишной стадии проекта.
Cпасибо за совет с breakpoint- сейчас почитаю

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma once
 
#include "stdafx.h"
#include <stdio.h>
#include <locale.h>
#include "curl/curl.h"
#include "Data.h"
#include "AllDataSaver.h"
#include "COM.h"
 
#pragma comment(lib,"curllib.lib")    // для VC++
//--------------------------------------------------------------------------
 
const size_t BUF_SIZE= 800000;
char   wr_buf[BUF_SIZE+1];  // char*   wr_buf[BUF_SIZE+1];
char TempBuf[7];
size_t  wr_index=0;
 
 
 
 //---------------------------------------------------------------------------
static size_t write_data(char *ptr, size_t size, size_t nmemb, char* data)
{
    if(data==NULL || wr_index + size*nmemb > BUF_SIZE) return 0; 
 
    memcpy( &data[wr_index], ptr, size*nmemb);// дописываем данные в конец
    wr_index+= size*nmemb;  // изменяем  текущее положение
 
    return size*nmemb;
}
//---------------------------------------------------------------------------
void internet()
{
 
    setlocale(0,"rus");
    //FILE * pFile;
    CURL *curl_handle;
    CURLcode res;
    
    curl_handle = curl_easy_init();
 
 
 
 
    if(curl_handle)
        {
            curl_easy_setopt(curl_handle, CURLOPT_URL, "http://api.openweathermap.org/data/2.5/weather?q=Dresden&mode=xml");
 
            curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, wr_buf);
            curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
 
            CURLcode res = curl_easy_perform(curl_handle);
 
            if(res == CURLE_OK)
              {
                  
               printf("%s\n Done!", wr_buf); // выводим буфер в консоль.
                
 
                pFile = fopen ( "myfile.txt" , "wb" );
                
                fwrite (wr_buf, 1 , sizeof(wr_buf) , pFile );
                fclose (pFile);
        
                        data("temperature value=\"",6,1);
                data("humidity value=\"",2,2);
                data("precipitation mode=\"",2,3);
                data("clouds value=\"",2,4);
                curl_easy_cleanup(curl_handle);
                
                
 
              }
            else printf( "curl_easy_perform() failed: %s\n", curl_easy_strerror(res) );
            
            
        }
 
    
    
}
0
19 / 19 / 6
Регистрация: 21.06.2015
Сообщений: 34
21.06.2015, 11:34
Лучший ответ Сообщение было отмечено 1nquisitor как решение

Решение

Ты же сам пишешь в комменте:
wr_index+= size*nmemb; // изменяем текущее положение

ну и
memcpy( &data[wr_index], ptr, size*nmemb);// дописываем данные в конец

То есть дописываешь в конец.

wr_index то ты между вызовами не обнуляешь как я вижу, вот он и пишет в конец

То есть нужно ткнуть
wr_index = 0
в начало функции
void internet()

Хотя делать несколько раз
curl_easy_init();
не круто и я рекомендовал бы эти все иниты убрать отсюда в начало программы.
0
 Аватар для 1nquisitor
4 / 4 / 1
Регистрация: 24.02.2014
Сообщений: 102
21.06.2015, 11:37  [ТС]
То чувство, когда ты понимаешь, что облажался...сам себе ошибку создал и сам ее искал
0
19 / 19 / 6
Регистрация: 21.06.2015
Сообщений: 34
21.06.2015, 12:16
Больше 20 лет программирую и могу с уверенностью сказать: ошибки они всегда такие, всегда именно сам себя перехитрил... Тут главный принцип - не верь себе.

Если придерживаться принципов отладки, тогда ошибки довольно быстро находятся.

Потому я про брейки и написал... Вот я пытаюсь представить, как бы ты мог ее сам найти:
Поставил брейк на память в конец буфера.
Он сработал на memcpy внутри write_data.
...Вот именно тут она, проблема...

Ты бы стал неминуемо смотреть значения переменных в этой строке.
Ну и довольно быстро обратил бы внимание на то, что с wr_index что-то не так.

Сложность как я понял была в том, что ты не знал где искать (потому и выложил другой кусок кода).
Так оно тоже всегда бывает... Поэтому брейки, вотчи, стек вызовов - нельзя предполагать где ошибка, нужно убедиться где именно падает при помощи дебагера.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.06.2015, 12:16
Помогаю со студенческими работами здесь

Не пойму где происходит переполнение массива
Я ошибся не переполнение, а выход за пределы #include &lt;iostream&gt; #include &lt;locale.h&gt; #include &lt;ctime&gt; using namespace std; ...

Переполнение стека в рекурсивной функции сортировки большого массива
Написал рекурсивную функцию сортировки массива, с массивами небольших размеров все работает как надо, а вот если сортирую побоьлше (60000...

Переполнение
При вводе слишком большого числа (например: 4444444444444444) программа зацикливается и постоянно выводит &quot;Ошибка. Введенный элемент...

Переполнение
Доброго времени суток! Есть код: void menu() { IndexList Universal; List *tmp = NULL; int punkt_menu; char *value =...

Переполнение стека
Привет народ. Такой вопрос: Если в общем виде: if (условие) double d else double d почему компилятор отказывается выполнять такое с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru