我知道你必须这样做:
int * p;
p = new int[10];
//use array
delete [] p;
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:由于没有明确说明,如何释放正确的内存量?操作系统是否跟踪分配的内存及其起始地址?
我正在尝试了解如何通过C语言中的引用传递参数.所以我写了这段代码来测试参数传递的行为:
#include <stdio.h>
#include <stdlib.h>
void alocar(int* n){
n = (int*) malloc( sizeof(int));
if( n == NULL )
exit(-1);
*n = 12;
printf("%d.\n", *n);
}
int main()
{
int* n;
alocar( n );
printf("%d.\n", *n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里印有:
12. 0.
例2:
#include <stdio.h>
#include <stdlib.h>
void alocar(int* n){
*n = 12;
printf("%d.\n", *n);
}
int main()
{
int* n;
n = (int*) malloc(sizeof(int));
if( n == NULL )
exit(-1);
alocar( n );
printf("%d.\n", *n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它打印:
12. …
我有一个类使用new运算符分配一些内存的方法,类的其他成员可以超出那个内存吗?课外怎么样?
如果我有一个包含带动态数组的字段的Delphi对象(包含例如字符串),如下所示:
TClassWithDynArrayField = class(TObject)
public
some_dyn_array : array of string;
end;
Run Code Online (Sandbox Code Playgroud)
当对象被销毁时,这个数组(和/或它的内容)会被自动释放/释放,还是我必须在对象的析构函数中以某种方式显式地完成它以避免内存泄漏或其他讨厌(垃圾中的崩溃)字符串和动态数组的收集器,或其他堆相关的代码等)?
如果答案是肯定的,那么一旦对象被销毁就会自动解除定位,同时也不会对字符串/动态数组垃圾收集产生任何不一致性,对于多级动态数组字段也是如此吗?例如这样:
TClassWithMultiLevelDynArrayField = class(TObject)
public
some_multi_level_dyn_array : array of array of string;
end;
Run Code Online (Sandbox Code Playgroud)
如果我改为使用定义这些数组(单级和/或多级)的"通用"方式(从我所听到的内部等同于"非通用"定义),答案是否会有任何不同动态数组,或不是吗?),如下:
TClassWithGenericMultiLevelDynArrayField = class(TObject)
public
some_generic_multi_level_dyn_array : TArray<TArray<string>>;
end;
Run Code Online (Sandbox Code Playgroud)
注意:对于所有这些示例,请假设其他代码将在对象被销毁之前随意填充所有级别的数组.
我之所以这么说是因为在对象(和动态分配的记录)中使用动态数组时,我经常会出现奇怪的访问冲突,并且在Delphi参考页面中有关于System.Finalize的一些半相关的讨论,看似区分动态数组的自动释放和例如字符串(即在基于Dispose的解除分配的情况下,但我认为它也可以应用于对象字段?),如下所示:
Finalize只应在Delphi代码中使用,其中动态分配的变量通过除Dispose过程之外的其他方式释放.动态数组永远不能使用Dispose过程释放,但可以通过将它们传递给Finalize来释放.
对于使用Dispose释放的全局变量,局部变量,对象和动态变量,编译器会生成代码,以在销毁实例时最终确定变量包含的所有长字符串,变量和接口.
如果动态变量满足以下两个条件,则需要调用Finalize以在变量可以被释放之前完成变量.
该变量通过除Dispose标准过程之外的其他方式释放(例如,使用FreeMem).
该变量包含长字符串,变体或接口,并非所有字符串都是空的或未分配的.
Finalize只是将所有长字符串设置为空,并将所有变量和接口设置为Unassigned,从而正确释放由长字符串和变体引用的任何内存.
请注意,在提到字符串的情况下,从未提及动态数组,并且在第一句中,动态数组被称为某种"手动"特殊情况?
因此,再次,Delphi对象字段中的动态数组将在对象被销毁时自动释放/释放,无论它们如何填充,例如字符串,并且无论它们是否是任意多个"级别深"(即内部的动态数组)动态数组),如上面的例子中所示?
我是C的新手,我正在尝试从文件中读取动态内存分配.至少我认为这就是我正在做的事情.
无论如何,这段代码有效:
int readfromfile(FILE *filepointer)
{
size_t size = 2;
char *str = (char *) malloc(sizeof(char));
int character = 0;
size_t counter = 0;
while((character = fgetc(filepointer)) != EOF)
{
str = (char *) realloc(str, size);
str[counter] = (char) character;
size ++;
counter++;
}
str[counter] = '\0';
printf("+%s+", str);
free(str);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
而且这段代码没有:
int main()
{
char *str = (char *) malloc(sizeof(char));
...
readfromfile(ifpointer, &str);
}
int readfromfile(FILE *filepointer, char **str)
{
size_t size = 2;
int character = …Run Code Online (Sandbox Code Playgroud) 所以,我有结构的列表和我分配的空间给他们用malloc(),使用*p.现在我想访问每个ptrletter元素并使用它.我该怎么办?这是我的代码.
typedef struct Words {
char *ptrletter;
int numbers;
} Word;
int main(){
FILE *f, *g;
char c,d;
int *a;
int nrofline=0;
int elements=0;
char string[2];
int lines=0;
f=fopen("m_in.txt","r");
do{
d=fgetc(f);
if (d=='\n'){
lines++;
}
}while (d!=EOF);
a=(int*)malloc(sizeof(int)*lines);
rewind(f);
lines=0;
do{
d=fgetc(f);
if ((d>='A' && d<='Z') || (d>='a' && d<='z')){
elements++;
}
if (d=='\n'){
a[lines]=elements;
lines++;
elements=0;
}
}while (d!=EOF);
Word *p=(Word*)malloc(sizeof(Word)*lines);
int j=0;
for (j=0; j<lines; j++){
strcpy(p[j].ptrletter,"");
p[j].numbers=0;
}
rewind(f);
}
Run Code Online (Sandbox Code Playgroud)
我在 …
我开始学习Fortran,来自C++/Matlab/Java背景.我意识到一些Fortran程序员仍然坚持使用F77,可能是因为他们不喜欢面向对象,命名空间和东西,并且习惯于旧的语法.
我知道你可以编写一个没有OOP的程序.我不明白的是没有动态内存管理你怎么做.有一千个例子,你事先不知道数组大小 - 例如将完整矩阵转换为稀疏矩阵时.
当然,现代Fortran提供"自动数组"和"可分配数组".但这些并没有出现在1977年.如果没有这些结构,F77的人如何管理?
我在使用malloc和getchar从用户那里读取类似内容时遇到了一些麻烦.我得到了结果,然而,我使用valgrind得到了内存泄漏.我对此很无能为力,并且问了我的同学和导师,但似乎没有人知道为什么.
char *ReadLineFile(FILE *infile){
int i=0;
char c;
char *newStringLine;
newStringLine = (char *) malloc(sizeof(char));
while( (c = fgetc(infile)) != '\n' ){
newStringLine[i++] = c;
realloc(newStringLine, (sizeof(char) * (i+1)));
}
newStringLine[i] = '\0';
return newStringLine;
}
Run Code Online (Sandbox Code Playgroud)
Valgrind给了我几个错误,包括1的无效写/读和无效的realloc.
考虑给定的2d数组分配:
int (*some)[10] = malloc(sizeof(int[10][10]));
Run Code Online (Sandbox Code Playgroud)
这将分配一个10 x 10 2d阵列.显然它的类型是int (*)[10].我想编写一个函数initialize()来分配它,初始化它然后返回一个指向数组的指针,这样构造some[i][j]就可以在其他函数中使用,这些函数可以将指针传递到彼此的数组.
原型应该是什么,特别是返回类型initialize()?
我将对象添加到函数中的向量。该代码如下所示:
class MyObj
{
int a;
int b;
MyObj( int ai, int bi )
{
this->a = ai;
this->b = bi;
}
};
vector<MyObj> myVec;
void foo()
{
MyObj objInst( 10, 20 );
myVec.push_back( objInst );
}
Run Code Online (Sandbox Code Playgroud)
我期望对象从堆栈中获取空间,因此在函数返回之后,应该释放它们的内存。以我的经验,事实并非如此,即到目前为止,可以在函数外部访问容器中的对象,没有问题。有人可以告诉我为什么会这样吗?STL容器是否复制传递给它们的对象的数据并将其保存在堆中或全局内存中?
非常感谢@Louen的评论。阅读这篇文章并学到了很多东西。 https://www.internalpointers.com/post/c-rvalue-references-and-move-semantics-beginners