Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C main函数从子程序接收到不正确的值_C - Fatal编程技术网

C main函数从子程序接收到不正确的值

C main函数从子程序接收到不正确的值,c,C,此代码不工作-将数据从子例程传递到主例程并分配内存时出现问题 子程序内部的计算是正确的,但main接收到的值是不正确的-main中的变量具有随机值,例如srate #include <stdio.h> #include <malloc.h> #include "sndfile.h" int main(int argc, char *argv[]) { int sRates , sRatem , ret; long nSamples=0, nSamp

此代码不工作-将数据从子例程传递到主例程并分配内存时出现问题

子程序内部的计算是正确的,但main接收到的值是不正确的-main中的变量具有随机值,例如srate

#include <stdio.h>
#include <malloc.h>
#include "sndfile.h"

int main(int argc, char *argv[])
{
    int sRates , sRatem , ret;
    long    nSamples=0, nSamplem;   
    float   *datas, *datam;


    printf("Read Test\n");
    if (argc != 3) {
        fprintf(stderr, "Expecting two wav file as argument\n");
        return 1;
    }


    ret =  readWav(argv[1], nSamples, sRates, &datas );
    if (ret != 0) {
    printf("Error\n");
    }
    // Output Info
    printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
        nSamples, argv[1], sRates, (float)nSamples/sRates);
    printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
        nSamples, argv[1], sRates, (float)nSamples/sRates);

//  free(datas);

    return 0;
}

int  readWav(char *fname, long *numFrames, int *sRate, float **buffer  ) 
{

    // Open sound file
    SF_INFO sndInfo;
    SNDFILE *sndFile = sf_open(fname, SFM_READ, &sndInfo);
    if (sndFile == NULL) {
        fprintf(stderr, "Error reading source file '%s': %s\n", fname, sf_strerror(sndFile));
        return 1;
    }


    printf("1Format of the audio file = %i\n", sndInfo.format);
    printf("2Number of channels = %i\n", sndInfo.channels);
    printf("3Sample Rate  = %d\n", sndInfo.samplerate);
    printf("4 Sample count  = %ld\n", (long)sndInfo.frames);
    sRate= sndInfo.samplerate;

    // Allocate memory
    buffer = (float *)malloc(sndInfo.frames * sndInfo.channels * sizeof(float));
    if (buffer == NULL) {
        fprintf(stderr, "Could not allocate memory for file\n");
        sf_close(sndFile);
        return 1;
    }

      // Load data
    numFrames = sf_readf_float(sndFile, buffer, sndInfo.frames);

    // Check correct number of samples loaded
    if (numFrames != sndInfo.frames) {
        fprintf(stderr, "Did not read enough frames for source\n");
        sf_close(sndFile);
        free(buffer);
//      return 1;
    }
    else {
        printf("Successfully read file\n");
        numFrames = sndInfo.frames;
    }
    // Output Info
    printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
//      numFrames, fname, sndInfo.samplerate, (float)numFrames/sndInfo.samplerate);
        numFrames, fname, sRate, (float)numFrames/sndInfo.samplerate);


    sf_close(sndFile);
//  return(buffer);
    return(0);

}
#包括
#包括
#包括“sndfile.h”
int main(int argc,char*argv[])
{
int sRates、sRatem、ret;
长nSamples=0,nSamplem;
浮点*数据,*数据M;
printf(“读取测试”);
如果(argc!=3){
fprintf(stderr,“需要两个wav文件作为参数\n”);
返回1;
}
ret=readWav(argv[1],nSamples,srate和data);
如果(ret!=0){
printf(“错误\n”);
}
//输出信息
printf(“从%s读取%ld帧,采样率:%d,长度:%fs\n”,
nSamples,argv[1],srate,(float)nSamples/srate);
printf(“从%s读取%ld帧,采样率:%d,长度:%fs\n”,
nSamples,argv[1],srate,(float)nSamples/srate);
//免费(数据);
返回0;
}
int readWav(char*fname,long*numFrames,int*sRate,float**buffer)
{
//打开声音文件
SF_信息sndInfo;
SNDFILE*SNDFILE=sf_打开(fname、SFM_读取和sndInfo);
if(sndFile==NULL){
fprintf(stderr,“读取源文件“%s”时出错:%s\n”,fname,sf_strerror(sndFile));
返回1;
}
printf(“1音频文件格式=%i\n”,sndInfo.format);
printf(“2个通道的数量=%i\n”,sndInfo.channels);
printf(“3采样率=%d\n”,sndInfo.samplerate);
printf(“4个样本计数=%ld\n”,(长)sndInfo.frames);
sRate=sndInfo.samplerate;
//分配内存
buffer=(float*)malloc(sndInfo.frames*sndInfo.channels*sizeof(float));
if(buffer==NULL){
fprintf(stderr,“无法为文件分配内存”\n);
sf_关闭(sndFile);
返回1;
}
//加载数据
numFrames=sf_readf_float(sndFile、buffer、sndInfo.frames);
//检查装载的样本数量是否正确
if(numFrames!=sndInfo.frames){
fprintf(stderr,“没有为源读取足够的帧\n”);
sf_关闭(sndFile);
自由(缓冲);
//返回1;
}
否则{
printf(“成功读取文件\n”);
numFrames=sndInfo.frames;
}
//输出信息
printf(“从%s读取%ld帧,采样率:%d,长度:%fs\n”,
//numFrames,fname,sndInfo.samplerate,(float)numFrames/sndInfo.samplerate);
numFrames,fname,sRate,(float)numFrames/sndInfo.samplerate);
sf_关闭(sndFile);
//返回(缓冲);
返回(0);
}

在C语言中,所有参数都是按值传递的,因此,如果需要类似于by ref的参数,则必须传递指针。由于您希望返回一个
浮点*
,因此需要传递一个
浮点**

实际上,您正在传递它,但您没有正确使用它(请使用
-Wall
或编译器的等效项来启用警告)

代码应该大致如下所示:

int  readWav(const char *fname, long *numFrames, int *sRate, float **buffer) 
{
    *buffer = malloc(...);
    //if you do not feel comfortable writing `*buffer` everywhere:
    float *data = *buffer;
    ///....
    *numFrames = sf_readf_float(...);
    ///....
    *sRate = sndInfo.samplerate;
    ///....
}

int main()
{
    long nSamples;
    int sRates;
    float *datas;
    ret =  readWav(argv[1], &nSamples, &sRates, &datas);
    //...
}

您的代码中有几个错误

#include <stdio.h>
#include "sndfile.h"

int  readWav(const char *const fname, long *numFrames, int *sRate, float **buffer);

int main(int argc, char *argv[])
{
    int   sRates, sRatem, ret;
    long  nSamples = 0, nSamplem;
    float *datas, *datam;


    printf("Read Test\n");
    if (argc != 3) {
        fprintf(stderr, "Expecting two wav file as argument\n");
        return 1;
    }


    ret = readWav(argv[1], &nSamples, &sRates, &datas);
    if (ret != 0) {
        printf("Error\n");
        return 1;
    }
    // Output Info
    printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
        nSamples, argv[1], sRates, (float)nSamples/sRates);
    printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
        nSamples, argv[1], sRates, (float)nSamples/sRates);
    free(datas);

    return 0;
}

int  readWav(const char *const fname, long *numFrames, int *sRate, float **buffer)
{
    // Open sound file
    SF_INFO sndInfo;

    if ((sRate == NULL) || (numFrames == NULL) || (buffer == NULL)) {
        fprintf(stderr, "Invalid arguments passed to readWav()\n");
        return 1;
    }

    SNDFILE *sndFile = sf_open(fname, SFM_READ, &sndInfo);
    if (sndFile == NULL) {
        fprintf(stderr, "Error reading source file '%s': %s\n", fname, sf_strerror(sndFile));
        return 1;
    }

    printf("1Format of the audio file = %i\n", sndInfo.format);
    printf("2Number of channels = %i\n", sndInfo.channels);
    printf("3Sample Rate  = %d\n", sndInfo.samplerate);
    printf("4 Sample count  = %ld\n", (long)sndInfo.frames);

    // Allocate memory
    *buffer = malloc(sndInfo.frames * sndInfo.channels * sizeof(float));
    if (*buffer == NULL) {
        fprintf(stderr, "Could not allocate memory for file\n");
        sf_close(sndFile);

        return 1;
    }

    *sRate = sndInfo.samplerate;
    // Load data
    *numFrames = sf_readf_float(sndFile, *buffer, sndInfo.frames);
    // Check correct number of samples loaded
    if (*numFrames != sndInfo.frames) {
        fprintf(stderr, "Did not read enough frames for source\n");
        sf_close(sndFile);
        free(*buffer);
    }
    else {
        printf("Successfully read file\n");
        *numFrames = sndInfo.frames;
    }
    // Output Info
    printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
        *numFrames, fname, *sRate, (float)*numFrames/sndInfo.samplerate);

    sf_close(sndFile);
    return(0);

}
  • 您没有声明
    readWav()
    ,而是从
    main()
    调用它,它的工作是巧合,因为它确实返回
    int

  • 您正在将
    datas
    的地址传递给
    readWav()
    ,请注意,
    &datas
    的类型为
    float**
    ,而
    readWav()
    应为
    float*

    如果你打开了编译器警告,你就会注意到这一点

  • 您正在将
    nSamples
    sRate
    的值传递给
    readWav()
    ,并且您希望main中的
    nSamples
    sRate
    得到初始化,您需要传递它们的地址

  • 您检查了
    readWav()
    的返回值,但仍然尝试访问
    datas
    指针

  • 这是您的代码的固定版本

    #include <stdio.h>
    #include "sndfile.h"
    
    int  readWav(const char *const fname, long *numFrames, int *sRate, float **buffer);
    
    int main(int argc, char *argv[])
    {
        int   sRates, sRatem, ret;
        long  nSamples = 0, nSamplem;
        float *datas, *datam;
    
    
        printf("Read Test\n");
        if (argc != 3) {
            fprintf(stderr, "Expecting two wav file as argument\n");
            return 1;
        }
    
    
        ret = readWav(argv[1], &nSamples, &sRates, &datas);
        if (ret != 0) {
            printf("Error\n");
            return 1;
        }
        // Output Info
        printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
            nSamples, argv[1], sRates, (float)nSamples/sRates);
        printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
            nSamples, argv[1], sRates, (float)nSamples/sRates);
        free(datas);
    
        return 0;
    }
    
    int  readWav(const char *const fname, long *numFrames, int *sRate, float **buffer)
    {
        // Open sound file
        SF_INFO sndInfo;
    
        if ((sRate == NULL) || (numFrames == NULL) || (buffer == NULL)) {
            fprintf(stderr, "Invalid arguments passed to readWav()\n");
            return 1;
        }
    
        SNDFILE *sndFile = sf_open(fname, SFM_READ, &sndInfo);
        if (sndFile == NULL) {
            fprintf(stderr, "Error reading source file '%s': %s\n", fname, sf_strerror(sndFile));
            return 1;
        }
    
        printf("1Format of the audio file = %i\n", sndInfo.format);
        printf("2Number of channels = %i\n", sndInfo.channels);
        printf("3Sample Rate  = %d\n", sndInfo.samplerate);
        printf("4 Sample count  = %ld\n", (long)sndInfo.frames);
    
        // Allocate memory
        *buffer = malloc(sndInfo.frames * sndInfo.channels * sizeof(float));
        if (*buffer == NULL) {
            fprintf(stderr, "Could not allocate memory for file\n");
            sf_close(sndFile);
    
            return 1;
        }
    
        *sRate = sndInfo.samplerate;
        // Load data
        *numFrames = sf_readf_float(sndFile, *buffer, sndInfo.frames);
        // Check correct number of samples loaded
        if (*numFrames != sndInfo.frames) {
            fprintf(stderr, "Did not read enough frames for source\n");
            sf_close(sndFile);
            free(*buffer);
        }
        else {
            printf("Successfully read file\n");
            *numFrames = sndInfo.frames;
        }
        // Output Info
        printf("Read %ld frames from %s, Sample rate: %d, Length: %fs\n",
            *numFrames, fname, *sRate, (float)*numFrames/sndInfo.samplerate);
    
        sf_close(sndFile);
        return(0);
    
    }
    

    srate
    是main的本地版本。传递指向它的指针。您在
    main
    之前没有声明
    readWav
    。如果这一切编译,它应该发出警告。如果你的函数使用了一个
    float*
    参数,并且你将
    datas
    声明为
    float*datas
    ,你认为
    &datas
    会是什么?另一方面,您尝试将
    sRate
    初始化为
    readWav()
    函数,但您传递了它的值而不是它的地址,因此确实需要
    运算符。基于
    readWav
    的代码,我怀疑
    nsample
    sRates
    也需要通过引用传递给它。@Squirrel:是的,你是对的。我没有读完前几行。。。我将把它添加到答案中。你的“float*data=*buffer;”语句背后的逻辑是什么?@user4504270:如果你只使用了几次缓冲区,那么它就一文不值了。但是,如果您必须多次访问数据,例如,为了进行计算,您必须编写
    (*buffer)[i]
    。这可能会变得很麻烦,而helper
    data
    允许您编写
    data[i]
    。谢谢。当发生错误时,readWav中有free(*buffer)-否则,是否需要释放。。。。如果是,何时何地?如果程序运行正常,为什么不需要释放缓冲区。。我猜如果它被释放,那么主接收NULL?在readWav中,为什么需要((sRate==NULL)| |(numFrames==NULL)| |(buffer==NULL))呢?这行被下移了-*sRate=sndInfo.samplerate-想知道为什么?此外,我不能返回“sndInfo.samplerate”-我必须将其赋值为*sRate,然后返回-为什么?Cleanup通常会清除作为指针的变量,如果它们不是NULL-例如float*datas,*datam;好奇的是,还有其他需要释放的吗?我是否也可以使用浮点数据,datam;-没有指针-但在readWav中,我相信我将丢失一个“*”I