Эта страница на официальном сайте mongodb адресует точно этот вопрос:
http://docs.mongodb.org/ecosystem/tutorial/model-data- for-ruby-on-rails /
Когда мы показываем наш список историй, нам нужно будет показать имя пользователя, разместившего историю. Если бы мы использовали реляционную базу данных, мы могли бы выполнить соединение с пользователями и магазинами и получить все наши объекты в одном запросе. Но MongoDB не поддерживает объединения, и поэтому время от времени требуется бит денормализации. Здесь это означает кеширование атрибута «имя пользователя».
Реляционные пуристы уже чувствуют себя неловко, как будто мы нарушаем какой-то универсальный закон. Но давайте иметь в виду, что коллекции MongoDB не эквивалентны реляционным таблицам; каждая из которых служит уникальной проектной цели. Нормализованная таблица обеспечивает атомный изолированный кусок данных. Однако документ более тесно представляет собой объект в целом. В случае сайта социальных новостей можно утверждать, что имя пользователя является неотъемлемой частью истории, опубликованной.
blockquote>
Вы не можете использовать strlen()
для неинициализированных данных:
blockquote>char* buffer = malloc(1000000); memset(buffer,0,strlen(buffer));
Нет способа для
strlen()
узнать размер выделенной памяти, так как он полагается на завершающий нулевой символ (0
,'\0'
), который может или не может быть где-то в памяти, на которую указывает буфер. Либо укажите размер памяти, выделенной вmemset()
:memset(buffer, 0, 1000000);
, либо используйте
calloc()
, который инициализирует выделенную память нулями:char buffer = calloc(1000000, sizeof(char)); // or calloc(1000000, 1) since sizeof(char) is 1 by definition.
. Могут быть другие проблемы. в вашем коде. Например, вы вызываете
DumpHex2()
дважды strike> вmain()
, но никогда не освобождаете память, которую выделяет функция. Память, выделенная дляsymbol
, также просочилась.Было бы легче ответить, если бы вы обновили свой вопрос, включив в него точный формат текста, который вы хотите
DumpHex2()
создать.Вы должны использовать
isprint()
, чтобы определить, печатается ли символ или нет.Короче и ИМХО легче читать и понимать:
#include <ctype.h> // isprint() #include <stddef.h> // size_t #include <stdlib.h> // malloc(), free() #include <string.h> // strcat() #include <stdio.h> // sprintf() enum { DUMP_BYTES_PER_LINE = 16, DUMP_BYTES_GROUP = 8, DUMP_CHARS_PER_LINE = DUMP_BYTES_PER_LINE * 4 + DUMP_BYTES_PER_LINE / DUMP_BYTES_GROUP + 4 }; char* DumpHex(const void* data, size_t size) { size_t const num_lines = size / DUMP_BYTES_PER_LINE + ((size % DUMP_BYTES_PER_LINE) > 0); size_t const result_length = num_lines * DUMP_CHARS_PER_LINE; char *result = malloc((result_length + 1) * sizeof(*result)); if (!result) return NULL; memset(result, ' ', result_length); result[result_length] = '\0'; char *dump_pos = result; char *plain_pos = result + DUMP_BYTES_PER_LINE * 3 + DUMP_BYTES_PER_LINE / DUMP_BYTES_GROUP + 3; char unsigned const *src = data; for (size_t i = 0; i < size; ++i, dump_pos += 3, ++plain_pos) { sprintf(dump_pos, "%02x ", (int)src[i]); dump_pos[3] = ' '; *plain_pos = isprint(src[i]) ? src[i] : '.'; if ((i + 1) % DUMP_BYTES_PER_LINE == 0 || i + 1 == size) { *++plain_pos = '\n'; size_t const bytes_per_line_left = (i + 1) % DUMP_BYTES_PER_LINE; plain_pos[bytes_per_line_left ? -(long long)bytes_per_line_left - 3 : -DUMP_BYTES_PER_LINE - 3] = '|'; dump_pos = plain_pos + 1 - 3; plain_pos = dump_pos + DUMP_BYTES_PER_LINE * 3 + DUMP_BYTES_PER_LINE / DUMP_BYTES_GROUP + 5; } else if ((i + 1) % DUMP_BYTES_GROUP == 0) { ++dump_pos; } } return result; }