Закодируйте вопрос с двумя суммами, используя C «элемент управления достигает конца функции, не являющейся недействительной»

#c

#c

Вопрос:

Я пытаюсь практиковать C, используя Leetcode, и ниже приведено мое решение для twoSum: https://leetcode.com/problems/two-sum /

Я протестировал свое решение с использованием gcc на виртуальной машине Linux, и код компилируется без предупреждений, а также дает правильное решение (проверено только в некоторых простых случаях).

Однако, когда я пытаюсь запустить тот же код в Leetcode, я продолжаю получать: «ошибка: управление достигает конца функции, не являющейся недействительной [-Werror=return-type] «

Может кто-нибудь, пожалуйста, объяснить, в чем проблема с моим кодом?

 int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    
    int result[2];
    int *result_ptr;
    result_ptr=malloc(sizeof(int)*2);
    result_ptr=resu<
    
    int i=numsSize-2;
    
    while(nums[numsSize-1]   nums[i] != target amp;amp; i != 0){
        i--;
    } 
    
    //value found
    if (i!=0 ||nums[numsSize-1]   nums[i] == target){
        result[0]=nums[numsSize-1];
        result[1]=nums[i];
        return result_ptr;
    }
    else{//value not found
        if(numsSize>2){
            twoSum(nums,numsSize-1,target,returnSize);
        }
        else{
            //premise states there will always be a solution
            //so this should never be reached
            return result_ptr;
        }
    }
}
  

Комментарии:

1. Я не знаю, что, по вашему мнению result_ptr=result , делает назначение, но, вероятно, оно не будет работать так, как вы ожидаете. Это приводит к утечке памяти и возврату указателя на локальный массив. Локальный массив, время жизни которого закончится, когда функция вернется и немедленно сделает указатель недействительным.

2. @Someprogrammerdude Спасибо за совет! Я использовал разделенный указатель, потому что в предпосылке упоминалось, что я должен malloc для возвращаемого значения (и для меня будет вызван free()).). Кроме того, в моем понимании, результатом будет указатель на первый элемент массива, а result_ptr=result будет просто указывать result_ptr на тот же элемент, не могли бы вы любезно объяснить, почему это может быть проблематично? Спасибо!

3. Сначала result_ptr=malloc(sizeof(int)*2) result_ptr указывает на память, которую вы только что выделили. Но затем result_ptr=result result_ptr указывает на что-то еще. Исходное значение result_ptr теряется. Это похоже int x; x = 5; x = 10; на, а затем удивляется, почему x больше не равно 5 .

Ответ №1:

У вас есть несколько проблем в коде, который вы показываете.

Сначала у нас есть проблемы, упомянутые в моих комментариях. Прежде всего, переназначение result_ptr приводит к потере исходного указателя, поэтому у вас больше нет доступа к выделенной вам памяти malloc . Это известно как утечка памяти.

Переназначение также приводит к другим проблемам, таким как возврат указателя на локальный result массив. Массив, который немедленно прекратит существование при возврате функции, делая возвращаемый указатель недействительным.

Это также приводит к проблеме, когда код позже пытается вернуть free возвращаемый указатель, поскольку возвращаемый вами указатель не возвращается malloc (или другой функцией выделения памяти).

Решение всех этих проблем заключается в том, чтобы result вообще не иметь массива. Удалите его, используйте result_ptr в качестве массива.


Затем для сообщения об ошибке, которое вы получаете.

В коде, который у вас есть

 if(numsSize>2){
    twoSum(nums,numsSize-1,target,returnSize);
}
else{
    //premise states there will always be a solution
    //so this should never be reached
    return result_ptr;
}
  

Здесь вы только явно возвращаетесь из функции в одной ветви. Другой, где вы вызываете twoSum рекурсивно, вообще не возвращается. Вместо этого код будет продолжаться за пределами if , и выполняться до конца функции. И это означает, что функция не вернет значение, что приведет к сообщению об ошибке.

Если функция объявлена для возврата значения, она должна возвращать значение явно и с использованием return инструкции. Эта проблема решается путем возврата того, что возвращает рекурсивный вызов:

 if(numsSize>2){
    // Explicitly return the result of the recursive call
    return twoSum(nums,numsSize-1,target,returnSize);
}
else{
    //premise states there will always be a solution
    //so this should never be reached
    return result_ptr;
}