C 动态内存和指针参数
我有两个函数,它们的作用是相同的——从一个只有整数的文件中读取每一行,并将它们存储在一个数组中: 我在main()函数中这样调用它们:C 动态内存和指针参数,c,function,pointers,C,Function,Pointers,我有两个函数,它们的作用是相同的——从一个只有整数的文件中读取每一行,并将它们存储在一个数组中: 我在main()函数中这样调用它们: StoreinArray1(X,大小,f) storeinaray2(X,大小,f) 第一个有效,但第二个无效 首先 int StoreinArray1(int X[], int *size, char *file) { int i=0; FILE *f; f = fopen(file, "r"); X = (int*) rea
StoreinArray1(X,大小,f)代码>
storeinaray2(X,大小,f)代码>
第一个有效,但第二个无效
首先
int StoreinArray1(int X[], int *size, char *file)
{
int i=0;
FILE *f;
f = fopen(file, "r");
X = (int*) realloc (X, *size * sizeof(int));
for (i=0;i<*size;i++)
{
fscanf(f, "%d", &X[i]);
}
return 1;
}
对于第一个,我使用了动态内存分配和实际计算的大小:
X = malloc(0);
while ((ch = fgetc(f)) != EOF)
{
if (ch == '\n')
lines++;
}
size = &lines;
就这一秒而言,我不能做同样的事。Visual Studio代码在我尝试时崩溃
所以我试着做*size=0
,然后做storeinaray2(X,size,f)代码>但它也不起作用
所以我的问题是关于第二个函数:
它是否在扫描文件时计算大小?假设没有必要使用动态内存分配(我的老师说)
如果是这样的话,我如何才能正确地传递一些“大小”参数?作为一个指针还是一个简单的整数
提前谢谢你
编辑:
以下是完整的第一个程序:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
int *size=0, *X, lines=1;
char *file = {"file.txt"};
char ch;
X = malloc(0);
f = fopen(file, "r");
while ((ch = fgetc(f)) != EOF)
{
if (ch == '\n')
lines++;
}
size = &lines;
StoreinArray(X, size, file);
}
int StoreinArray(int X[], int *size, char *file)
{
int i=0;
FILE *f;
f = fopen(file, "r");
X = (int*) realloc (X, *size * sizeof(int));
for (i=0;i<*size;i++)
{
fscanf(f, "%d", &X[i]);
}
for (i=0;i<*size;i++)
printf("%d\n",X[i]);
return 1;
}
首先,我必须打开main中的文件来计算行数。我知道我在main中忘记了fclose(f)和free(X),但是根据这些指令,VSC崩溃了
程序的第二个版本的问题是main中的size
声明。将其声明为int,而不是指向int的指针。您当前的程序正在崩溃,因为您没有为大小分配任何空间,并且当StoreInArray尝试更新它时,您遇到了访问冲突。所以,main应该是这样的:
int main()
{
int X[100];
int size;
char *file = {"file.txt"};
size = 0;
StoreinArray(X, &size, file);
}
好的,我会尽力解释清楚,并解释我能找到的所有东西
首先,我们需要讨论变量、指针和内存,因为您似乎对这些概念没有很好的理解。一旦点击,其余的应该很容易跟随
首先,简单变量。那部分很简单,我想你或多或少都明白这一点
int x; // This is an integer variable. It's not initialized, so its value could be anything
int meaning = 42; // This is another integer variable. Its value will be 42.
double pi = 3.14; // A variable with digits after the decimal point
char c = 15; // Another inte... well, yes, actually, char is also an integer.
char c2 = 'a'; // Nice, this also counts. It's converted to an integer behind the scenes.
等等
与阵列类似:
int arr[10]; // Array with 10 values. Uninitialized, so they contain garbage.
int arr2[3] = { 1, 2, 3 }; // Array with 3 values, all initialized
int arr3[] = {1, 2, 3, 4, 5}; // Array with 5 values.
数组基本上只是一次创建的一组变量。创建数组时,C需要知道大小,并且大小必须是一个固定的数字-不能使用其他变量。这是有原因的,但这是技术性的,我不想再谈这个了
现在谈谈记忆。这些变量中的每一个都将存储在计算机的RAM中。精确的位置是不可预测的,每次运行程序时可能会有所不同
现在,RAM就像一个字节的huuuge数组。有字节数0
、字节数1
,等等。一个int
变量占用4个字节,因此它可以,例如,以字节数120
、121
、122
和123
结束
单个变量(或单个数组)中的所有字节将在RAM中彼此相邻。两个不同的变量可能会在RAM的另一端结束,但每个变量中的字节将在一起
现在我们来讨论指针的概念。指针基本上只是一个整数变量。它包含其他变量的第一个字节的RAM号。让我们看一个例子:
int i = 42;
int *p = &i;
假设变量i
存储在字节数200
…203
(即4个字节)中。在这些字节中,我们有值42
。然后假设变量p
存储在字节数300
…303
(这是另外4个字节)中。这4个字节将包含值200
,因为这是i
变量的第一个字节
这也是程序员在说“
的”(内存)地址”或“指向
的指针”时的意思。这是
的RAM中第一个字节的数目。因为同一变量的所有字节都粘在一起,所以通过知道第一个字节(以及知道变量的类型),您可以找出
的其余部分在内存中的位置
现在,让我们在示例中再添加一行:
*p = 5;
在这种情况下,计算机所做的是获取存储在p
中的地址,进入内存中的该位置,将以下4个字节视为一个整数,并将值5
放在那里。因为我们之前已将p
设置为“点”“在地址i
处,这与简单地设置i
变量本身具有相同的效果
好的,你都明白了吗?这是一个有点棘手的问题,通常需要一段时间才能解决。为了理解它,请随时重读一遍。你需要它来继续前进
准备好了吗?好的,让我们谈谈堆栈和动态内存
当程序启动时,操作系统会自动为它分配一点内存,只是为了让它更容易启动。它就像一个大的字节数组,都在内存中。现在它通常是1MB左右,但它可以变化。这种内存称为“堆栈”。为什么这么叫?嗯,我改天再解释
不管怎么说,当你的main()
函数启动时,操作系统会像“给你,我的好朋友,一个指向堆栈的指针。你认为合适的时候就可以使用它了!祝你有愉快的一天!”
然后,您的main()
函数使用它来存储您在其中生成的所有变量。所以当你像p=&i
那么存储在p
中的地址就在堆栈的某个地方
现在,当main()
调用另一个函数时,例如StoreinArray()
,它也会给它一个指向堆栈的指针,并说“好的,这是指向堆栈的指针。小心,我已经使用了它的前XXX字节,但可以随意使用其余的”
然后StoreinArray()
使用堆栈将其变量放在那里。当StoreinArray()
调用其他对象时,它也会执行相同的操作,而且会不断地执行
现在,有几个
int arr[10]; // Array with 10 values. Uninitialized, so they contain garbage.
int arr2[3] = { 1, 2, 3 }; // Array with 3 values, all initialized
int arr3[] = {1, 2, 3, 4, 5}; // Array with 5 values.
int i = 42;
int *p = &i;
*p = 5;
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
int *size=0, *X, lines=1;
char *file = {"file.txt"};
char ch;
X = malloc(0);
f = fopen(file, "r");
while ((ch = fgetc(f)) != EOF)
{
if (ch == '\n')
lines++;
}
size = &lines;
StoreinArray(X, size, file);
}
int StoreinArray(int X[], int *size, char *file)
{
int i=0;
FILE *f;
f = fopen(file, "r");
X = (int*) realloc (X, *size * sizeof(int));
for (i=0;i<*size;i++)
{
fscanf(f, "%d", &X[i]);
}
for (i=0;i<*size;i++)
printf("%d\n",X[i]);
return 1;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *file = "file.txt";
FILE *f = fopen(file, "r");
int *X, lines=1;
char ch;
while ((ch = fgetc(f)) != EOF)
{
if (ch == '\n')
lines++;
}
fclose(f);
X = (int *)malloc(lines * sizeof(int));
StoreinArray(X, lines, file);
}
void StoreinArray(int X[], int lines, char *file)
{
int i=0;
FILE *f = fopen(file, "r");
for (i=0;i<lines;i++)
{
fscanf(f, "%d", &X[i]);
}
fclose(f);
for (i=0;i<lines;i++)
printf("%d\n",X[i]);
}
int main()
{
int X[100];
int *size;
char *file = {"file.txt"};
*size = 0;
StoreinArray(X, size, file);
}
int StoreinArray(int X[], int *size, char *file)
{
FILE *f;
f = fopen(file, "r");
if (f == NULL)
return -1;
*size = 0;
while (!feof(f))
{
if (fscanf(f, "%d", &X[*size]) == 1)
*size++;
}
fclose(f);
return 1;
}
#include <stdio.h>
#include <stdlib.h>
#define MAX_X 100
int main()
{
int X[MAX_X];
char *file = "file.txt";
int lines;
lines = StoreinArray(X, MAX_X, file);
}
int StoreinArray(int X[], int maxLines, char *file)
{
FILE *f;
int lines;
f = fopen(file, "r");
if (f == NULL)
return -1;
while (!feof(f))
{
if (fscanf(f, "%d", &X[lines]) == 1)
lines++;
if (lines == maxLines)
break;
}
fclose(f);
return lines;
}