关于将2D阵列转换为1D阵列存在很多问题,但我正在尝试恰恰相反。我正在尝试将字符串分区为常量长度的子字符串,并将它们放在2D数组中。此2D矩阵的每一行应包含初始字符串的子字符串,如果要连续读取每一行并连接,则应重现初始字符串。
我几乎让它工作,但由于某种原因,我丢失了初始字符串(bin)的第一个子字符串(partitions [0] - length 8 * blockSize):
int main (void){
char* bin = "00011101010000100001111101001101000010110000111100000010000111110100111100010011010011100011110000011010";
int blockSize = 2; // block size in bytes
int numBlocks = strlen(bin)/(8*blockSize); // number of block to analyze
char** partitions = (char**)malloc((numBlocks+1)*sizeof(char)); // break text into block
for(int i = 0; i<numBlocks;++i){
partitions[i] = (char*)malloc((8*blockSize+1)*sizeof(char));
memcpy(partitions[i],&bin[8*i*blockSize],8*blockSize);
partitions[i][8*blockSize] = '\0';
printf("Printing partitions[%d]: %s\n", i, partitions[i]);
}
for(int j=0; j<numBlocks;++j)
printf("Printing partitions[%d]: %s\n", j,partitions[j]);
return 0;
}
输出如下:
Printing partitions[0]: 0001110101000010
Printing partitions[1]: 0001111101001101
Printing partitions[2]: 0000101100001111
Printing partitions[3]: 0000001000011111
Printing partitions[4]: 0100111100010011
Printing partitions[5]: 0100111000111100
Printing partitions[0]: Hj
Printing partitions[1]: 0001111101001101
Printing partitions[2]: 0000101100001111
Printing partitions[3]: 0000001000011111
Printing partitions[4]: 0100111100010011
Printing partitions[5]: 0100111000111100
第一个for循环中的分区构造成功。在读出构造之后,分区[0]处的字符串包含垃圾值。任何人都可以提供一些见解吗?
答案 0 :(得分:0)
他们的代码存在一些问题。
您正在错误地分配**partitions
。
而不是:
char** partitions = (char**)malloc((numBlocks+1)*sizeof(char)); /* dont need +1, as numblocks is enough space. */
您需要为char*
指针分配空间,而不是char
个字符。
相反,这需要:
char** partitions = malloc((numBlocks+1)*sizeof(char*));
另请阅读Why not to cast result of malloc(),因为C中不需要它。
malloc()
,因为它可能会在失败时返回NULL
。
malloc()
先前请求的free()
内存总是好的。在程序中的某个时刻执行此操作非常重要。 以下是一些显示此内容的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCKSIZE 2
#define BLOCK_MULTIPLIER 8
int main(void) {
const char *bin = "00011101010000100001111101001101000010110000111100000010000111110100111100010011010011100011110000011010";
const size_t blocksize = BLOCKSIZE;
const size_t multiplier = BLOCK_MULTIPLIER;
const size_t numblocks = strlen(bin)/(multiplier * blocksize);
const size_t numbytes = multiplier * blocksize;
char **partitions = malloc(numblocks * sizeof(*partitions));
if (partitions == NULL) {
printf("Cannot allocate %zu spaces\n", numblocks);
exit(EXIT_FAILURE);
}
for (size_t i = 0; i < numblocks; i++) {
partitions[i] = malloc(numbytes+1);
if (partitions[i] == NULL) {
printf("Cannot allocate %zu bytes for pointer\n", numbytes+1);
exit(EXIT_FAILURE);
}
memcpy(partitions[i], &bin[numbytes * i], numbytes);
partitions[i][numbytes] = '\0';
printf("Printing partitions[%zu]: %s\n", i, partitions[i]);
}
printf("\n");
for(size_t j = 0; j < numblocks; j++) {
printf("Printing partitions[%zu]: %s\n", j,partitions[j]);
free(partitions[j]);
partitions[j] = NULL;
}
free(partitions);
partitions = NULL;
return 0;
}
输出非垃圾值:
Printing partitions[0]: 0001110101000010
Printing partitions[1]: 0001111101001101
Printing partitions[2]: 0000101100001111
Printing partitions[3]: 0000001000011111
Printing partitions[4]: 0100111100010011
Printing partitions[5]: 0100111000111100
Printing partitions[0]: 0001110101000010
Printing partitions[1]: 0001111101001101
Printing partitions[2]: 0000101100001111
Printing partitions[3]: 0000001000011111
Printing partitions[4]: 0100111100010011
Printing partitions[5]: 0100111000111100
答案 1 :(得分:0)
int numBlocks = strlen(bin)/(8*blockSize); // number of block to analyze
char** partitions = (char**)malloc((numBlocks+1)*sizeof(char)); // break text into block
for(int i = 0; i<numBlocks;++i){
partitions[i] = (char*)malloc((8*blockSize+1)*sizeof(char));
memcpy(partitions[i],&bin[8*i*blockSize],8*blockSize);
partitions[i][8*blockSize] = '\0';
printf("Printing partitions[%d]: %s\n", i, partitions[i]);
}
这一切对我来说都很可疑;它对于任务而言过于复杂,使其成为错误的主要嫌疑人。
void *
返回的malloc
指针以及其他函数不应该进行投标。sizeof (char)
始终 1在C中)。事实上,在您第一次致电malloc
时,您应该乘以sizeof (char *)
(或者更好,sizeof *partitions
,如下例所示),因为它的大小是partitions
指向的元素类型。malloc
可能会返回NULL
,当您尝试分配到其指向的位置时,会导致未定义的行为。NULL
,malloc
或calloc
返回时,其他任何内容(即不是realloc
}的所有内容都需要free
d不再使用,或者valgrind这样的工具(泄漏检测程序,对于习惯性地忘记free
分配对象并因此导致内存泄漏的人有用)将报告误报并丢失部分内容有用性。numBlocks
,i
或其他任何用于计算数组元素的内容都应声明为size_t
以遵循标准约定(例如,检查{{ 3}},概要部分,了解如何声明strlen
,注意返回值的类型是size_t
)。由溢出引起的负值显然会导致程序行为异常。我建议使用单个分配,例如:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCK_SIZE 8
int main(void) {
char const *bin = "00011101010000100001111101001101000010110000111100000010000111110100111100010011010011100011110000011010";
size_t bin_length = strlen(bin),
block_count = (bin_length / BLOCK_SIZE)
+ (bin_length % BLOCK_SIZE > 0); // excess as per point 6 above
char (*block)[BLOCK_SIZE + 1] = malloc(block_count * sizeof *block);
if (!block) { exit(EXIT_FAILURE); }
for (size_t x = 0; x < block_count; x++) {
snprintf(block[x], BLOCK_SIZE + 1, "%s", bin + x * BLOCK_SIZE);
printf("Printing partitions[%zu]: %s\n", x, block[x]);
}
for (size_t x = 0; x < block_count; x++) {
printf("Printing partitions[%zu]: %s\n", x, block[x]);
}
free(block);
exit(0);
}