Прощай, Мир!
1672 / 829 / 253
Регистрация: 26.05.2012
Сообщений: 3,057
1
MASM

Выделение динамической памяти для строки. Вывод строки. Строка выводится кракозябрами

20.05.2019, 20:49. Показов 2244. Ответов 5
Метки нет (Все метки)

здр. имеется следующая программа.. при выводе сообщения со строками из динамической памяти выводятся кракозябры.. пжл, подскажите мне что я делаю не так..

напишите процедуру, которая принимает дескриптор хипа (динамическая память) и смещение строки.. процедура выделяет достаточно памяти на хипе, чтобы сохранить строку три раза.. затем в хип записывается три копии строки.. процедура возвращает указатель на выделенную память.. используя эту процедуру выведите строку с хипа и освободите память..
Assembler
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
82
83
.386
.model flat,stdcall
 
option casemap:none
 
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib    
 
.data
hnd dd ?
buf dd ?
arr db "I love you!"
len = $-arr
times dd ?
 
.code
main proc
    invoke HeapCreate,HEAP_NO_SERIALIZE,0,0
 
    mov hnd,eax
 
    push eax    
 
    mov eax,offset arr
 
    push eax
 
    call strheap
 
    invoke ExitProcess,0
main endp
 
strheap proc
    push ebp        
    mov ebp,esp
 
    mov eax,3
    mov ecx,len
    mul ecx
    inc eax
 
    mov times,eax
 
    mov ebx,[ebp+12]    
 
    invoke HeapAlloc,ebx,HEAP_NO_SERIALIZE,times
 
    mov buf,eax
 
    mov edi,eax
    mov ecx,3
    three:
        push ecx
 
        mov esi,[ebp+8]
        mov ecx,len
        copy:
            lodsb
            stosb
        loop copy
 
        pop ecx
    loop three
    
    mov byte ptr [edi],0
 
    invoke MessageBoxA,NULL,ADDR buf,NULL,MB_OK
 
    invoke HeapFree,hnd,NULL,buf
 
    invoke HeapDestroy,hnd
 
    pop ebp         
 
    retn 8          
strheap endp
end main
Добавлено через 8 минут
Цитата Сообщение от proc3nt Посмотреть сообщение
invoke MessageBoxA,NULL,ADDR buf,NULL,MB_OK
ой, все.. решил проблему..
Assembler
1
invoke MessageBoxA,NULL,buf,NULL,MB_OK
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.05.2019, 20:49
Ответы с готовыми решениями:

Выделение и удаление памяти, выделенной для динамической строки
Данная функция производит ввод и собственно контроль ввода (размер массива от 1 до 20, иначе должна...

Выделение памяти для строки
Почему размер строки первой 4 байта а второй 50 байт?Первая должна сколько же. #include <stdio.h>...

Выделение памяти для строки символов
Нужно выделить память под массив указателей на строки, ввести текст построчно динамически выделяя...

Выделение памяти для большой строки
Здравствуйте! Необходиом выделить память большого размера для массива - текстовой информации (...

5
Эксперт Hardware
Эксперт Hardware
5442 / 1981 / 361
Регистрация: 29.07.2014
Сообщений: 2,898
Записей в блоге: 4
20.05.2019, 23:33 2
proc3nt, вообще-то у процесса есть уже куча, а ты создаёшь ещё одну..
её хендл возвращает GetProcessHeap().
по-сути это даже не хендл, а адрес начала текущей кучи в памяти.
теперь этот адрес/хендл можешь подставлять в алокатор,
причём если выставить в нём флаг(Zero), то выделенная память забьётся нулями,
который будет служит терминальным нулём при выводе строки на экран.
Assembler
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
format      pe gui
include    'win32ax.inc'
 
.data  ;---------
hndl       dd   0
buff       dd   0
str0       db  'Example '
sLen       =    $-str0
 
.code  ;---------
start:     invoke   GetProcessHeap    ; запросить дескриптор текущей кучи
           mov      [hndl],eax        ;
           push     eax str0          ; дескриптор кучи, и адрес строки
          stdcall   strheap           ;
 
           invoke   MessageBox,0,[buff],0,0
           invoke   HeapFree,[hndl],0,[buff]
           invoke   ExitProcess,0
;------
proc       strheap, string, handle
           invoke   HeapAlloc,[handle],1000b,sLen*4   ; флаг "HEAP_ZERO_MEMORY"
           mov      [buff],eax
           mov      esi,[string]                      ; аргумент со-стека (источник)
           mov      edi,eax                           ; приёмник = выделенная куча
           push     esi esi                           ; для трёх раз
           mov      ebx,3                             ; счётчик
@@:        mov      ecx,sLen                          ; длина строки для rep
           rep      movsb                             ; копируем!
           pop      esi                               ; восстановить источник
           dec      ebx                               ;
           jnz      @b                                ; повторить 3-раза
           ret                                        ;
endp
.end start
1
Прощай, Мир!
1672 / 829 / 253
Регистрация: 26.05.2012
Сообщений: 3,057
21.05.2019, 09:06  [ТС] 3
Цитата Сообщение от R71MT Посмотреть сообщение
sLen*4
R71MT, спасибо за предоставленную информацию.. довольно-таки познавательно..
только почему ты выделяешь память именно в четыре раза большую, чем длина исходной строки?
0
Эксперт Hardware
Эксперт Hardware
5442 / 1981 / 361
Регистрация: 29.07.2014
Сообщений: 2,898
Записей в блоге: 4
21.05.2019, 11:59 4
Цитата Сообщение от proc3nt Посмотреть сообщение
в четыре раза большую, чем длина исходной строки?
..это от фонаря (всё-равно там 4-страницы пустуют)
можешь сделать sLen+1
Вот скрины где показано, что дефолтная куча лежит по адресу 80000,
а после выделения в ней памяти, указатель смещается на некоторое кол-во байт, причём там валяется мусор (см.скрин 2). А вот если установить флаг "Heap_Zero_Memory", то выделенная область забивается нулями - хвост будет маркером конца строки.
Миниатюры
Выделение динамической памяти для строки. Вывод строки. Строка выводится кракозябрами   Выделение динамической памяти для строки. Вывод строки. Строка выводится кракозябрами  
1
Прощай, Мир!
1672 / 829 / 253
Регистрация: 26.05.2012
Сообщений: 3,057
21.05.2019, 12:55  [ТС] 5
Цитата Сообщение от R71MT Посмотреть сообщение
можешь сделать sLen+1
R71MT, ты наверное имел ввиду
sLen*3+1
1
-10 / 4 / 1
Регистрация: 20.05.2019
Сообщений: 16
21.05.2019, 13:15 6
Цитата Сообщение от R71MT Посмотреть сообщение
это от фонаря
все правильно строки то тоже разные бывают, если широкие - размерчик то что надо
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.05.2019, 13:15
Помогаю со студенческими работами здесь

Динамическое выделение памяти для строки
Добрый день. Такой вопрос возник: При создании строки с помощью указателя на char и ввода с помощью...

Динамическое выделение памяти для строки
Подскажите, пожалуйста , почему в данной программе появляются ошибки в строке return Vector(v1.x...

Выделение нужного количества памяти для строки
Задача состоит в том, чтобы считать кол-во символов в файле, выделить ровно под эту строку память,...

Выделение динамической памяти для char
Здравствуйте, возник вопрос: как выделить память для char массива? Вот, что делаю я: #include...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru