此代码不起作用-将数据从子例程传递到main并分配内存的问题。

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

#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);

}

最佳答案

您的代码中有几个错误


您没有声明readWav(),而是从main()调用它,这是巧合,即因为它确实返回了int
您正在将datas的地址传递给readWav(),请注意,&datas的类型为float **,而readWav()需要一个float *

如果您打开了编译器警告,则您会注意到这一点。
您正在将nSamplessRate的值传递给readWav(),并且期望主目录中的nSamplessRate得到初始化,您需要传递它们的地址。
您检查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);

}


提示:应该尝试以仅具有一个退出点的方式编写函数,我喜欢使用goto,尽管虔诚的程序员对goto持肯定态度,但它会使您的代码更易读,更一致,更易于维护。

我的意思是,您可以拥有一个标签,在该标签中您可以从函数中返回错误代码并进行所有清理,类似这样

int function()
{
    /* set errorCode */
    if (firstFailureCondition == 1)
        goto cleanup;
    if (secondFailureCondition == 1)
        goto cleanup;
                 .
                 .
                 .
    if (nthFailureCondition == 2)
        goto cleanup;
cleanup:
    /* do your cleanup */
    return errorCode;
}

关于c - 函数主从子例程接收到不正确的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28205315/

10-11 18:55