0

我有一个结构数组,每个结构都描述了我所说的信号。我以这种方式声明了我的结构:

 /* Structure for keywords */
 struct varStruct
 {
    char* varName;
    int varOccurence;
 } signals[MAX_SIGNALS];

我正在一个循环中工作,该循环分析文件并动态查找信号声明,在我的例子中称为newArrayName 。我想做的是,仅当尚未包含读取信号时才将读取信号添加到数组中。否则,我应该增加 varOccurence 变量。

这是我的代码,但我有一个分段错误(所以没有更多信息)......

    // We are in the loop that get the signals sequentially
    char* newArrayName = TheValueOfTheReadSignal.

    int i;
    // We browse all the array...
    for(i=0; i < MAX_SIGNALS; i++)
    {
        // If a signal already has the name of the currently-read signal, we inc its occurence
        if(strcmp(signals[i].varName, newArrayName) == 0)
        {
            signals[i].varOccurence++;
        }
        // Otherwise, we add a new signal with the read-name and an occurence corresponding to the value of a static variable that's incremented after each signal-reading.
        else
        {
            signals[index_Array].varName = newArrayName;
            signals[index_Array].varOccurence = index_Array;

        }
    }
     // We increment index_Array, which is a static int variable
       index_Array ++;
    // End of the loop that gets the signals 

这会导致分段错误。我的C语言不是很好,我什至会说我很不擅长。我这里的猜测是信号数组还没有初始化,所以 signal[i] 对他没有任何意义,但是我不知道如何初始化一个结构体数组。也许是另一个原因,我不知道。

非常感谢您的帮助。

4

3 回答 3

2

一个问题是,在第一次迭代中,所有varName成员要么要么是未初始化的指针,要么NULL是未初始化的指针(取决于signals声明的位置)。确保它们被初始化为NULL

struct varStruct
{
    char* varName;
    int varOccurence;
} signals[MAX_SIGNALS] = { {0} };

NULL并在传递给之前检查它是否是strcmp()

if(signals[i].varName && strcmp(signals[i].varName, newArrayName) == 0)

如果varName为 NULL,则表示没有填充其他元素,您可以填充它并从循环中中断。

另外确保:

  • 分配给 的值varName是动态分配的(malloc()例如使用)并且只要需要就可以存在,记住free() varName何时不再需要。
  • index_Array小于MAX_SIGNALS填充 的元素之前signals
于 2012-05-02T15:22:35.203 回答
2
  1. 您正在搜索循环本身内创建一个“新”条目。几乎每次都会立即创建一个新条目。只有在所有现有条目都不匹配后,您才应该创建新条目;即在你完成循环之后。

  2. 你不应该一直循环,MAX_SIGNALS因为一开始,你的大部分数组都是空的。只有第一个index_Array元素是真实的。这也使您无需使用 NULL 指针初始化结构并检查它们,因为无论如何您都不会遍历未初始化的条目。

  3. 你在index_Array盲目地增加。仅在您真正添加条目时才增加。

一些变化:

// We are in the loop that get the signals sequentially
char* newArrayName = TheValueOfTheReadSignal.

int found_entry;
found_entry = FALSE; /* A flag that remembers if the entry has been found.  */

for(i=0; i < index_Array; i++)
{
    if(strcmp(signals[i].varName, newArrayName) == 0)
    {
        signals[i].varOccurence++;
        found_entry = TRUE;
        break;
    }
}
if (!found_entry)
{
    signals[index_Array].varName = newArrayName;
    signals[index_Array].varOccurence = index_Array++;
}
于 2012-05-02T15:23:12.190 回答
1

当您在记录中没有条目时signals,或者当i大于记录条目数减一时,strcmp(signals[i].varName, newArrayName)尝试取消引用无效(未初始化或NULL)指针signals[i].varName

除此之外,一旦index_Array变得与MAX_SIGNALS(或更大)一样大,

// We browse all the array...
for(i=0; i < MAX_SIGNALS; i++)
{
    // If a signal already has the name of the currently-read signal, we inc its occurence
    if(strcmp(signals[i].varName, newArrayName) == 0)
    {
        signals[i].varOccurence++;
    }
    // Otherwise, we add a new signal with the read-name and an occurence corresponding to the value of a static variable that's incremented after each signal-reading.
    else
    {
        signals[index_Array].varName = newArrayName;
        signals[index_Array].varOccurence = index_Array;

    }
}
 // We increment index_Array, which is a static int variable
   index_Array ++;

您写到数组的末尾,这是未定义的行为,可能会直接导致内存损坏和/或分段错误,或者作为内存损坏的结果。

signals[index_Array]在您的循环中,每次找到具有不同名称的信号时都会写入,并且index_Array每次循环运行后都会递增,无论您是否已经有一些具有该名称的信号。您应该检查是否已经记录了信号,并且只有在没有写入新条目和增量的情况下index_Array

// Check for newArrayName == NULL and exit or otherwise handle the situation if it is
// We browse all the array...
for(i=0; i < index_Array && i < MAX_SIGNALS; i++)
{
    // If a signal already has the name of the currently-read signal, we inc its occurence
    if(signals[i].varName != NULL && strcmp(signals[i].varName, newArrayName) == 0)
    {
        signals[i].varOccurence++;
        break; // we already have that signal, can stop looping
    }
}
// Check if i == MAX_SIGNALS
// if it is, we have no more space in the array,
// that needs handling
if (i == index_Array && index_Array < MAX_SIGNALS) {
    // We haven't had that signal before, record it
    signals[index_Array].varName = newArrayName;
    signals[index_Array].varOccurence = index_Array;
    // And increment index_Array, which is a static int variable
    index_Array ++;
}
于 2012-05-02T15:23:49.570 回答