The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Релиз Chrome 80"
Отправлено Аноним84701, 05-Фев-20 20:37 
Гм-хм, вы слишком переоцениваете "откровение" из детского мультика: "Как вы яхту назовете ...".

> Как научишься создавать многомерный массив на куче, а не на стеке, приходи поговорим

Предпочту подождать с разговором, пока анонимный "Уважаемый", "Знаток", "Эксперт" (эпитет "Скромный" не упомянут видимо из скромности) не подучит матчасть 🙄


cat arr3.c &&  gcc -O2 arr3.c && ./a.out 2 2 1 1337
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DIM 3
#define TYPE int

const size_t ARR_LEN = DIM * DIM * DIM ;
const size_t ARR_SIZE = ARR_LEN * sizeof(TYPE);

typedef TYPE array[DIM][DIM][DIM];
void foo(array bar, int x, int y, int z, char val) {
        bar[x][y][z] = val;
}

int main(int argc, char** argv) {
    array *arr = malloc(ARR_SIZE);
    for (size_t i = 0; i < ARR_LEN; i++) {
        *((TYPE*)arr + i) = atoi(argv[4]) + i;
        printf ("%p:%lu = %lu\n",((TYPE*)arr + i), i, atoi(argv[4]) + i);
    }
    foo(*arr, atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), atoi(argv[4]) + 1);
    
    for (size_t x = 0; x < DIM; x++)
        for(size_t y = 0; y < DIM; y++)
            for(size_t z = 0; z < DIM; z++)
              printf("[%lu][%lu][%lu]: %d\n",  x,y,z, (*arr)[x][y][z]);

    return 0;
}
0x800a45000:0 = 1337
0x800a45004:1 = 1338
0x800a45008:2 = 1339
0x800a4500c:3 = 1340
...
0x800a45060:24 = 1361
0x800a45064:25 = 1362
0x800a45068:26 = 1363
[0][0][0]: 1337
[0][0][1]: 1338
[0][0][2]: 1339
..
[2][1][2]: 1360
[2][2][0]: 1361
[2][2][1]: 58
[2][2][2]: 1363


foo:
.LFB1:
        .cfi_startproc
# arr3.c:12: void foo(array bar, int x, int y, int z, char val) {
        mov     eax, DWORD PTR [esp+8]  # x, x
# arr3.c:13:         bar[x][y][z] = val;
        mov     ecx, DWORD PTR [esp+4]  #, bar
        mov     edx, DWORD PTR [esp+12] # y, y
        lea     eax, [eax+eax*8]        # tmp95,
        lea     eax, [ecx+eax*4]        # tmp97,
        movsx   ecx, BYTE PTR [esp+20]  # val, val
        lea     edx, [edx+edx*2]        # tmp100,
        add     edx, DWORD PTR [esp+16] # tmp101, z
        mov     DWORD PTR [eax+edx*4], ecx      # *_3, val
# arr3.c:14: }
        ret    
        .cfi_endproc

(это все помимо того, что абсолютно никто не мешает обернуть обращение к одномерному массиву в макрос и не париться - но … раз анонимы в книжке^W на стековерфлоу прочитали "нужно использовать массив указателей на указателей, иначе никак!", то так и будут, не задумываясь, их использовать 🙄)

И, чтобы начать немного соответствовать никам, не забудьте завернуть доказательства, что последовательная загрузка из _таблицы указателей_ :


void foo2(int*** bar, int x, int y, int z, char val) {
    bar[x][y][z]
}

foo2:
.LFB1:
        .cfi_startproc
# arr3.c:14:     bar[x][y][z] = val;
        movsx   rsi, esi        # x, tmp107
        movsx   rdx, edx        # y, tmp108
        movsx   rcx, ecx        # z, tmp109
        movsx   r8d, r8b        # val, tmp110
        mov     rax, QWORD PTR [rdi+rsi*8]      # *_3, *_3
        mov     rax, QWORD PTR [rax+rdx*8]      # *_7, *_7
        mov     DWORD PTR [rax+rcx*4], r8d      # *_11, val
# arr3.c:16: }
        ret    
        .cfi_endproc


будет быстрее вычисления адреса (особенно при размерах, кратных 2-м).
foo:
.LFB1:
        .cfi_startproc
# arr3.c:13:         bar[x][y][z] = val;
        movsx   rsi, esi        # x, tmp101
        movsx   rdx, edx        # y, tmp102
        movsx   rcx, ecx        # z, tmp103
        movsx   r8d, r8b        # val, tmp104
        sal     rsi, 10 # tmp93,
        sal     rdx, 4  # tmp97,
        add     rsi, rdi        # tmp94, tmp100
        add     rdx, rcx        # tmp98, z
        mov     DWORD PTR [rsi+rdx*4], r8d      # *_3, val
# arr3.c:14: }
        ret    
        .cfi_endproc

 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру