为什么我们不能动态分配指向函数的指针?

时间:2017-08-14 22:02:36

标签: c arrays function pointers malloc

我尝试动态分配指向类似

的函数的指针
void (*f)(void*);
f = (*f)malloc(sizeof(f) * 2);

我收到了一个错误。

  

错误:预期';'之前' malloc'

在我搜索之后,我发现我们无法动态地为函数分配指针,我们只能将它声明为数组。在第一步中,我声明它是一个函数数组

void (f[2])(void*);

我看到我得到另一个错误,我不能声明一个函数数组,我必须声明它是一个函数指针数组。

void (*f[2])(void*);

在我的搜索中,我也发现,指向函数的指针并不指向数据,它指向代码。 如果有人能解释我为什么我们不能动态地分配一个函数指针,为什么我们不能有一个函数数组而不是函数指针数组。

我的代码如下:

#include <stdio.h>
#include <stdlib.h>

void printNr(void *nr)
{
    printf("%i\n", nr);
}

void printChar(void *ch)
{
    printf("%c\n", ch);
}

int  main(void)
{
    void (*f)(void*);
    f = (*f)malloc(sizeof(f) * 2);
    f = printNr;
    (f  + 1) = printChar;
    (*f)(15);
    (*(f  + 1))('t');
    return (0);
} 

3 个答案:

答案 0 :(得分:4)

如果要为指向int **arr = malloc(sizeof(*arr) * n); 的指针数组动态分配空间,则需要加倍**(指向指针的指针)

sizeof

对于一个指向函数的指针数组,你需要一个双**然后取消引用才能得到#include <stdio.h> #include <stdlib.h> void fn1(void *val) { puts((char *)val); } void fn2(void *val) { puts((char *)val); } int main(void) { void (**f)(void*); f = malloc(sizeof(*f) * 2); f[0] = fn1; f[1] = fn2; f[0]("Hello"); f[1]("Bye"); free(f); return 0; }

import smtplib, os
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.utils import formatdate
from email import encoders

attachment_path=r'C:\Directory'+'\\'

login='login'
password='password'
part=MIMEBase('application',"octet-stream")

def message(attachment): #attachment is just the PDF file name
    fromaddr = "example@example.com"
    cc=fromaddr
    msg = MIMEMultipart()
    msg['From'] = fromaddr
    msg['To'] = "example@example.com"
    msg['Date'] = formatdate(localtime = True)
    msg['Subject'] = "Subject"

    body='''
    <!DOCTYPE html>
    <html>
    <body>

    <p><font face="Tahoma" size=2> I hope everything is going well.</p></font> 

    </body>
    </html>
    '''
    msg.attach(MIMEText(body, 'html'))
    part.set_payload(open(attachment_path+attachment,'rb').read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', 'attachment; filename="{0}"'.format(os.path.basename(attachment_path+attachment)))
    msg.attach(part)

    mail=smtplib.SMTP('Server',587)
    mail.ehlo()
    mail.starttls()
    mail.login(login,password)
    mail.sendmail(fromaddr,[toaddr,cc],msg.as_string())

答案 1 :(得分:1)

澄清 -

  1. 为函数分配内存是不合逻辑的,因为你不打算复制函数的代码:)* 1。您只需指定函数所在的内存地址。功能已经在内存中。
  2. 由于与1.中相同的原因,您无法创建函数数组。您只能创建指向函数的指针数组。
  3. *在嵌入式开发中,如果必须从RAM运行函数,RAM有限,并且需要释放另一个,它有时会使用它。但通常它是静态存储位置而不是动态存储位置。

答案 2 :(得分:1)

在您定义的两个函数中存在各种错误定义(如果不是实际上未定义的)行为。您使用该代码危险地(充其量)生活。您可以定义函数以获取int,然后它就可以了(也可以更改函数指针类型)。

但是,我认为这与您的直接问题相关 - (*f)之前的malloc()是完全虚假的。如果你想在那里进行强制转换,你需要(void (**)(void *))来指定指向函数的指针,该函数返回void并获取void *参数。

这里的固定代码的功能类型按建议更改:

#include <stdio.h>
#include <stdlib.h>

static void printNr(int nr)
{
    printf("%i\n", nr);
}

static void printCh(int ch)
{
    printf("%c\n", ch);
}

int main(void)
{
    void (**f)(int);
    f = (void(**)(int))malloc(sizeof(*f) * 2);
    f[0] = printNr;
    f[1] = printCh;
    (*f)(15);
    (*(f  + 1))('t');
    free(f);
    return(0);
}

请注意,分配(f[0]f[1])也已修复。如果您必须使用非数组表示法,那么*(f + 0)*(f + 1)将是自洽的,*f*(f+1)也可以使用。

将typedef用于指向函数类型的指针会更容易。

#include <stdio.h>
#include <stdlib.h>

typedef void (*FunctionPtr)(int);

static void printNr(int nr)
{
    printf("%i\n", nr);
}

static void printCh(int ch)
{
    printf("%c\n", ch);
}

int main(void)
{
    FunctionPtr *f = (FunctionPtr *)malloc(sizeof(*f) * 2);
    f[0] = printNr;
    f[1] = printCh;
    (*f)(15);
    (*(f  + 1))('t');
    free(f);
    return(0);
}

请注意,在定义函数时无法使用typedef。即使您定义了函数类型而不是函数指针类型,您也无法做到这一点,这是C的奇怪怪癖。例如,给定typedef void Function(int);,您无法定义static Function printNr { … }或类似的任何内容,并且其含义与定义的函数相同。尝试static Function *returnsPtr(int n) { … }编译(如果正文合适)但返回一个函数指针(Function *FunctionPtr)。

如果你正在使用C编译器,则不需要来自malloc()的强制转换。如果您正在使用C ++编译器,则需要它。代码(两个程序)释放分配的内存。两个程序都没有检查分配 - 拍手腕。