简体   繁体   English

我如何为这个二维数组动态分配空间有什么问题?

[英]What is wrong with how I'm dynamically allocating space for this 2d array?

I'm trying to create a 2D array that will store be able to store each character of a .txt file as an element in the 2D array.我正在尝试创建一个二维数组,该数组将能够将 .txt 文件的每个字符存储为二维数组中的一个元素。

How do I dynamically allocate space for it?如何为其动态分配空间?

This what I've done so far to malloc it.这是我到目前为止为 malloc 所做的。 (this was copied of GeeksForGeeks) (这是 GeeksForGeeks 的复制品)

char *arr[rownum2];

for (i = 0; i < rownum2; i++) {
    arr[i] = (char *)malloc(colnum * sizeof(char));

However, I think this is the source of serious memory related issues later on in my program, and I've also been told some parts of this are unnecessary.但是,我认为这是我的程序后面与内存相关的严重问题的根源,而且我还被告知其中的某些部分是不必要的。

Can I please get the most suitable way to dynamically allocate memory for the 2D array in this specific scenario?在这种特定情况下,我能否获得最合适的方法来为二维数组动态分配内存?

The code you have posted is 'OK', so long as you remember to call free() on the allocated memory, later in your code, like this:您发布的代码是“OK”的,只要您记得在分配的内存上调用free() ,稍后在您的代码中,如下所示:

for (i=0;i<rownum2;i++) free(arr[i]);

...and I've also been told some parts of this are unnecessary. ...而且我还被告知其中的某些部分是不必要的。

The explicit cast is unnecessary , so, instead of:显式转换是不必要的,所以,而不是:

arr[i] =  (char *)malloc(colnum*sizeof(char));

just use:只需使用:

arr[i] =  malloc(colnum*sizeof(char));

The sizeof(char) is also, strictly speaking, unnecessary ( char will always have a size of 1 ) but you can leave that, for clarity.严格来说, sizeof(char)也是不必要的( char的大小始终为1 ),但为了清楚起见,您可以保留它。

Technically, it's not a 2D array, but an array of arrays.从技术上讲,它不是二维数组,而是数组的数组。 The difference is, you can't make 2D array with lines of different size, but you can do it with your array of arrays.不同的是,你不能用不同大小的线制作二维数组,但你可以用你的数组数组来做。

If you don't need it, you can allocate rownum2*colnum elements and access each element as arr[x+colnum*y] (it's used often because all data are kept in one place, decreasing CPU cache load and some system inner needs for storing each pointer of each allocated chunk).如果不需要,可以分配rownum2*colnum元素,将每个元素作为arr[x+colnum*y] (经常使用,因为所有数据都放在一个地方,减少 CPU 缓存负载和一些系统内部需求用于存储每个分配块的每个指针)。

Also, even array of lines of different sizes can be placed into 1D array and accessed like 2D (at least, if they do not change size or even RO).此外,即使是不同大小的线数组也可以放入一维数组中并像二维一样访问(至少,如果它们不改变大小甚至 RO)。 You can allocate char body[total_size] , read the whole array, allocate char* arr[rownum2] and set each arr[i]=body+line_beginning_offset .您可以分配char body[total_size] ,读取整个数组,分配char* arr[rownum2]并设置每个arr[i]=body+line_beginning_offset

BTW don't forget there are not actual C strings because they are not null-terminated.顺便说一句,不要忘记没有实际的 C 字符串,因为它们不是以空字符结尾的。 You'll need an additional column for null-term.您将需要一个额外的空项列。 If you store ASCII art, 2D array is a very good solution.如果您存储 ASCII 艺术,二维数组是一个非常好的解决方案。

The only serious problem I see in your code is that you are casting the returned value of malloc(3) , and probably you have forgotten to #include <stdlib.h> also (this is a dangerous cocktail), and this way, you are destroying the returned value of the call with the cast you put before malloc(3) .我在您的代码中看到的唯一严重问题是您正在转换malloc(3)的返回值,而且您可能还忘记#include <stdlib.h> (这是一种危险的鸡尾酒),这样,您正在使用您在malloc(3)之前放置的演员表破坏调用的返回值。 Let me explain:让我解释:

  • First, you have (or haven't, but I have to guess) a 64bit architecture (as it is common today) and pointers are 64bit wide in your system, while int integers are 32bit wide.首先,您拥有(或没有,但我必须猜测)64 位体系结构(今天很常见)并且您的系统中的指针是 64 位宽,而int整数是 32 位宽。
  • You have probably forgotten to #include <stdlib.h> in your code (which is something I have to guess also), so the compiler is assuming that malloc(3) is actually a function returning int (this is legacy in C, if you don't provide a prototype for a function external to the compilation unit), so the compiler is generating code to get just a 32 bit value from the malloc(3) function, and not the 64bit pointer that (probably, but I have to guess also) malloc(3) actually returns.你可能忘记在你的代码中#include <stdlib.h> (这也是我必须猜测的),所以编译器假设malloc(3)实际上是一个返回int的函数(这是 C 中的遗留,如果您没有为编译单元外部的函数提供原型),因此编译器正在生成代码以从malloc(3)函数中获取 32 位值,而不是 64 位指针(可能,但我有也猜测) malloc(3)实际上返回。
  • You are casting that int 32bit value (already incorrect) to a 64bit pointer (far more incorrect, but I have to guess...), making any warning about type conversions between integer values and pointers to dissapear, and be silenced when you put the cast (the compiler assumes that, as a wise programmer you are, you have put the cast there on purpose, and that you know what you are doing)您正在将int 32bit 值(已经不正确)转换为 64bit 指针(更不正确,但我必须猜测......),使有关整数值和指针之间的类型转换的任何警告消失,并在您放置时静音演员表(编译器假定,作为一个聪明的程序员,你是故意把演员表放在那里的,而且你知道自己在做什么)
  • The first (undefined behaviour) returned value is being (undefined behaviour) just cut to 32 bit, and then converted (from int to char * , with more undefined behaviour) to be used in your code.第一个(未定义的行为)返回的值是(未定义的行为)只是切成 32 位,然后转换(从intchar * ,具有更多未定义的行为)以在您的代码中使用。 This makes the original pointer returned from malloc(3) to be completely different value when reinterpreted and cast to (char *) .这使得从malloc(3)返回的原始指针在重新解释并转换为(char *)时是完全不同的值。 This makes your pointers to point to a different place, and break your program on execution.这会使您的指针指向不同的位置,并在执行时中断您的程序。

Your code should be something like (again, a snippet has to be used, as your code is not complete):您的代码应该类似于(同样,必须使用一个片段,因为您的代码不完整):

#include <stdlib.h> /* for malloc() */

/* ... */

char *arr[rownum2];

for (i = 0; i < rownum2; i++) {
    arr[i] = malloc(colnum); /* sizeof(char) is always 1 */

I need finally to do you a recommendation:最后我需要给你一个建议:

Please, read (and follow) the how to create a minimal, verifiable example page, as your probable missing #include error, is something I had to guess.... Posting snippets of code makes many times your mistakes to go away, and we have to guess what can be happening here.请阅读(并遵循)如何创建一个最小的、可验证的示例页面,因为您可能缺少#include错误,这是我不得不猜测的......我们必须猜测这里会发生什么。 This is the most important thing you have to learn from this answer.这是您必须从这个答案中学到的最重要的事情。 Post complete, compilable and verifiable code (that is, code that you can check fails, before posting, not a snippet you selected where you guess the problem can be).发布完整的、可编译的和可验证的代码(即,在发布之前,您可以检查失败的代码,而不是您选择的可能出现问题的片段)。 The code you posted does allow nobody to verify why it can be failing, because it must be completed (and repaired, probably) to make it executable.您发布的代码确实不允许任何人验证它为什么会失败,因为它必须完成(并且可能已修复)才能使其可执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM