功能中的分段故障

时间:2013-05-22 22:38:09

标签: c debugging segmentation-fault callstack

当我运行调试时,它指向line: 105(并在左角写入“分段错误”)。我不知道“调用堆栈”窗口中的红线是什么意思......

请告诉它是什么,我在哪里可以阅读更多信息。

这是函数的代码:

/* Separates stereo file's samples to L and R channels. */
struct LandR sepChannels_8( unsigned char *smp, unsigned long N, unsigned char *L, unsigned char *R, struct LandR LRChannels )
{
    int i;

    if ( N % 2 == 0 )   // Each channel's (L,R) number of samles is 1/2 of all samples.
    {
        L = malloc(N / 2);
        R = malloc(N / 2);
    }
    else
        if ( N % 2 == 1 )
        {
            L = malloc(N + 1 / 2);
            R = malloc(N + 1 / 2);
        }

    int m = 0;
    for ( i = 0; i < N; i++ )    // separating
    {
        L[m] = smp[2 * i + 0];   // THIS IS THE "LINE: 105"
        R[m] = smp[2 * i + 1];
        m++;
    }
    return LRChannels; 
}

这里是窗户的画面(更容易展示而不是试图描述)

enter image description here

3 个答案:

答案 0 :(得分:1)

红线是您的调用堆栈:基本上,它告诉您问题发生在sepChannels_8()函数内部,该函数是从main()调用的。事实上,sepChannels_8()函数中存在一些错误。

以下是我的分析:

struct LandR sepChannels_8(unsigned char *smp, unsigned long N, unsigned char *L, unsigned char *R, struct LandR LRChannels)

sepChannels_8是一个函数,它接受五种不同类型的参数,并返回一个struct LandR类型的值。但是,不清楚传递给函数的五个参数是什么。 unsigned char *smp似乎是指向您的音频示例的指针,其中unsigned long N是示例总数。但unsigned char *Lunsigned char *Rstruct LandR LRChannels,一点也不清楚。你没有使用它们。 unsigned char *Lunsigned char *R,您的函数会立即丢弃任何传入的指针,将其替换为使用malloc()分配的内存,然后将其丢弃而不是free() d,并且只对struct LandR LRChannels执行的操作只是将其保持不变。

{
    int i;

    if ( N % 2 == 0 )   // Each channel's (L,R) number of samles is 1/2 of all samples.
    {
        L = malloc(N / 2);
        R = malloc(N / 2);
    }
    else
        if ( N % 2 == 1 )
        {
            L = malloc(N + 1 / 2);
            R = malloc(N + 1 / 2);
        }

现在这很有趣:如果传入的unsigned longN是偶数,则使用malloc()分配两个存储块,每个N / 2大小,并将其分配给LR。如果N不均匀,则仔细检查以查看它是否为奇数,如果是,则使用malloc()分配两个存储块,每个N的大小,并将其分配给LR。我想你可能打算分配两个大小为(N + 1) / 2的存储块,但是在加法和减法之前会发生乘法和除法,所以这不是你得到的。如果N既不奇也不奇,你也无法解释会发生什么。那没关系,因为毕竟这是一个不可能的条件......那你为什么要测试这种可能性呢?

    int m = 0;
    for ( i = 0; i < N; i++ )    // separating
    {
        L[m] = smp[2 * i + 0];   // THIS IS THE "LINE: 105"
        R[m] = smp[2 * i + 1];
        m++;
    }

大部分非常标准:你有一个循环,一个计数器,以及要遍历的数组。但是,您的终止条件是错误的。您一次两步走下smp数据,并且通过乘以数组索引来实现,因此您的索引计数器需要从0运行到N / 2,不是从0N。 (另外,如果N奇怪......),您需要考虑最后一项。此外,您同时使用mi同样的事情。其中一个是不必要的,多余的,不需要的,额外的。

    return LRChannels;
}

并且,返回传递给函数的LRChannels结构,未经修改。与此同时,您要丢弃LR变量,这些变量包含指向malloc()的指针 - 分配的存储空间,现已丢失。

LR应该是什么?看起来好像它们应该是unsigned char **,所以你可以通过存储指针将你分配的存储返回给调用者......或者struct LandR有两个指针元素,您打算在返回结构之前将LR保存在结构中?对于LR以及LRChannels,我不明白为什么要将它们传递给函数。您也可以在函数内部创建所有自动变量,就像int iint m一样。

答案 1 :(得分:0)

您在数组中有mallocN/2元素,但在循环中,您的计数器从0变为N。这意味着您正在尝试访问从0到N的元素,因为您在每次迭代时都会增加m。显然,你会遇到一个段错误。

答案 2 :(得分:0)

'smp'的价值是什么?

它需要在调用sepChannels_8()之前分配,或者指向有效的占位符。