l->nextが と等しくない場合は何も返さないため、この関数の動作は未定義NULLです。
//...
if (l->next != NULL)
l->next = delete_node (l->next, limit);
else
return l;
}
このコードスニペットでも
if (l->age < limit){
struct list* tmp;
tmp = l->next;
free(l);
}
lポイントされたメモリを削除した後、ポインタに無効な値が含まれています。
関数は次の方法で実装できます
struct list * delete_node( struct list *l, int limit )
{
if ( l != NULL )
{
if ( l->age < limit )
{
struct list *tmp = l;
l = l->next;
free( tmp );
l = delete_node( l, limit );
}
else
{
l->next = delete_node( l->next, limit );
}
}
return l;
}
ここにデモンストレーションプログラムがあります。リストを表示する関数も再帰関数として記述します。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct list
{
int age;
struct list *next;
};
struct list * delete_node( struct list *l, int limit )
{
if ( l != NULL )
{
if ( l->age < limit )
{
struct list *tmp = l;
l = l->next;
free( tmp );
l = delete_node( l, limit );
}
else
{
l->next = delete_node( l->next, limit );
}
}
return l;
}
void display( struct list *l )
{
if ( l == NULL )
{
puts( "null" );
}
else
{
printf( "%d -> ", l->age );
display( l->next );
}
}
int push_front( struct list **l, int age )
{
struct list *current = malloc( sizeof( struct list ) );
int success = current != NULL;
if ( success )
{
current->age = age;
current->next = *l;
*l = current;
}
return success;
}
int main(void)
{
enum { Lower = 7, Upper = 20 };
struct list *head = NULL;
srand( ( unsigned int )time( NULL ) );
for ( int i = Lower; i < Upper; ++i )
{
int age = rand() % ( Upper - Lower + 1 ) + Lower;
push_front( &head, age );
}
display( head );
head = delete_node( head, ( Upper + Lower ) / 2 );
display( head );
head = delete_node( head, Upper + 1 );
display( head );
return 0;
}
プログラムの出力は次のようになります
14 -> 11 -> 8 -> 15 -> 8 -> 13 -> 16 -> 18 -> 11 -> 8 -> 18 -> 13 -> 12 -> null
14 -> 15 -> 13 -> 16 -> 18 -> 18 -> 13 -> null
null