如何在函数

时间:2015-12-21 20:02:05

标签: c arrays memory dynamic

我正在尝试从用户那里收到一个号码。 并创建一个具有该数字的数组,但是在函数内部。 这是我的几次尝试,我遇到了运行时错误。 非常感谢帮助。

#include <stdio.h>
#include <stdlib.h>
int* Init(int* p, int num);
int main() {
    int *p;
    int num, i;
    puts("Enter num of grades:");
    scanf("%d", &num);

    Init(&p, num);
    //for (i = 0; i < num; i++)
    //{
    //  scanf("%d", &p[i]);
    //}
    free(p);
}
int* Init(int* p, int num)
{
    int *pp;
    p = (int *)malloc(num*sizeof(int));
    if (!pp)
    {
        printf("Cannot allocate memory\n");
        return;
    }
    p = pp;
    free(pp);
}

5 个答案:

答案 0 :(得分:4)

你已经做得很好,你知道你需要将指针传递给指针。但是你的函数签名不需要int **。您将指针传递给指针并将分配的内存存储在其中:

void Init(int **pp, int num)
{
    int *p;
    p = malloc(num*sizeof(int));
    if (!p)
    {
        printf("Cannot allocate memory\n");
    }
    *pp = p;
}

并检查Init()是否返回正确的指针:

   Init(&p, num);
   if(p == NULL) {
      /*Memory allocation failed */
   }

或者分配内存并返回指针:

int* Init(int num)
{
    int *p;
    p = malloc(num*sizeof(int));
    if (!p)
    {
        printf("Cannot allocate memory\n");
    }

    return p;
}

并从main()调用:

int * p = Init(num);
if(p == NULL) {
   /*Memory allocation failed */
}

相应地更改Init()的原型。

在任何情况下,您都不得free() Init()中的指针。这只是立即取消分配内存,你将留下dangling pointer

完成后,您需要free()main()

答案 1 :(得分:1)

首先,您需要修复函数的原型。它应该是

int* Init(int** p, int num);  

然后修复功能定义

int* Init(int** p, int num)
{
    //int *pp;   // You don not need this variable
    *p = malloc(num*sizeof(int));   // Allocate memory
    if (!*p)
    {
        printf("Cannot allocate memory\n");
        return NULL; // Return a NULL pointer
    }

    return *p;
}  

答案 2 :(得分:1)

Sub Rectangle1_Click()

Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset

'Drive code for Access
'con.ConnectionString = "DBO=C:\Temp\MyAccess.accdb:" & _
"Driver = (Microsoft Access Dirver (*.accdb));"

'Actual ConnectionString
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.Path & "\MyAccess.accdb;"

'Derived ConnectionString
'In the Immediate Window, paste the following...
'?createobject("DataLinks").PromptNew.ConnectionString
'con.ConnectionString = "Provider=MSDASQL.1;Persist Security Info=False;Extended Properties=DSN=MS Access Database;DBQ=C:\Temp\MyAccess.accdb;DefaultDir=C:\Temp;DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeout=5;UID=admin;"

'Open DB Connection
con.Open

Set rs.activeconnection = con

rs.Open "Select * from SharePrices"

StartRow = 3

Do Until rs.EOF
    'First Field
    Cells(StartRow, 4) = rs.Fields(1).Value
    'Second Field
    Cells(StartRow, 5) = rs.Fields(2).Value
    'Third Field
    Cells(StartRow, 6) = rs.Fields(3).Value
    rs.movenext
    StartRow = StartRow + 1
Loop

rs.Close
Set rs = Nothing
con.Close
Set con = Nothing

' RECORD A SIMPLE MACRO TO DELETE THE DATA POINT THAT YOU WANT TO ELIMINATE

End Sub
int *pp;
p = (int *)malloc(num*sizeof(int));
if (!pp) /* pp is used uninitialized at this point */

如果要为另一个函数内的int *p; int num, i; puts("Enter num of grades:"); scanf("%d", &num); Init(&p, num); free(p); /* p is used uninitialized at this point */ 指针分配空间,则需要将指针传递给指针:

int

答案 3 :(得分:0)

代码中的一些拼写错误

p = (int *)malloc(num * sizeof(int));

应该是

pp = (int *)...

你的free(pp);是导致它无法正常工作的原因,你不想调用它,否则你分配的内存将不会被保存。 pp的记忆本质上也是“失去的”#34;在函数调用结束时作为Init p的方法参数是一个值副本,不是对main的{​​{1}}版本的精确引用,因此当Init时返回时,p的更改已丢失&#39;

只需执行:p和初始p = Init();

精通: 此行return pp;将变量p = pp设置为指向由p分配的内存,因此免费pp也可以免费pp。 我不确定将地址返回到内存总是被认为是好习惯,因为你必须确保它被释放,但是对于你的程序它可以工作。

答案 4 :(得分:0)

知道您的函数不会修改您的指针 (*p) 非常重要,**p 丢失并且 *p 在 Main 函数中没有有效且已知的内存地址。

为了安全分配内存,我建议使用这两个函数。

void init(int **p,int number){
    *p =  malloc(number*sizeof(int));
}

如果你想让你的函数返回分配的指针,你可以这样做:

int* init(int number){
    int* p = malloc(number*sizeof(int));
    return p;
}