C main函数从子程序接收到不正确的值
此代码不工作-将数据从子例程传递到主例程并分配内存时出现问题 子程序内部的计算是正确的,但main接收到的值是不正确的-main中的变量具有随机值,例如srateC 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
#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]
。这可能会变得很麻烦,而helperdata
允许您编写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