مخرجات مختلفة بعد تصحيح الأخطاء وتجميع برامج C ++
-
22-09-2019 - |
سؤال
أقوم بتشغيل CodeBlocks على برنامج التحويل البرمجي Mingw في جهاز Virtual XP. كتبت في بعض الكود البسيط ، يمكن الوصول إليه في CL1P ، الذي يجيب على سؤال الخوارزمية في CODECKEF (حسنًا ، إنه يجيب عليه جزئيًا فقط ، حيث لم أقم بتضمين الحلقة بعد لحالات الاختبار المتعددة.
ومع ذلك ، فإن مشكلتي هي أنه أثناء تشغيله في وضع التصحيح ، فإنه يعطي الإخراج الصحيح من 5 ، للمدخلات:
3
1
2 1
1 2 3
ومع ذلك ، عندما أقوم ببناءها وتشغيلها ، فإنه يعطي الناتج الضخم ، 131078 ، ما يبدو وكأنه قمامة بالنسبة لي. لا أفهم كيف يحدث هذا بحق الجحيم ، لكنني أعتقد أنه يتعلق بتخصيص الذاكرة الديناميكية. ما هي المشكلة هنا ، وكيف يمكنني إصلاحها؟ حتى أنني ركضت من خلال المترجم عبر الإنترنت في بوتسكول, ، وعملت بشكل جيد. بعد إضافة الحلقة لحالات الاختبار ، عملت الرمز بشكل صحيح على CODECKEF!
#include <iostream>
using namespace std;
int main()
{
// Take In number of rows
int numofrows;
cin >> numofrows;
// Input Only item in first row
int * prevrow;
prevrow = new int[1];
cin >> prevrow[0];
// For every other row
for (int currownum = 1; currownum < numofrows; currownum++)
{
// Declare an array for that row's max values
int * currow;
currow = new int[currownum+1];
int curnum;
cin >> curnum;
// If its the first element, max is prevmax + current input
currow[0] = prevrow[0] + curnum;
// for every element
int i = 1;
for (; i <= currownum; i++)
{
cin >> curnum;
// if its not the first element, check whether prevmax or prev-1max is greater. Add to current input
int max = (prevrow[i] > prevrow[i-1]) ? prevrow[i] : prevrow[i-1];
// save as currmax.
currow[i] = max + curnum;
}
// save entire array in prev
prevrow = new int[i+1];
prevrow = currow;
}
// get highest element of array
int ans = 0;
for (int j=0; j<numofrows; j++)
{
if (prevrow[j] > ans)
{
ans = prevrow[j];
}
}
cout << ans;
}
المحلول
لشيء واحد ، هذا:
//save entire array in prev
prevrow = new int [i+1];
prevrow = currow;
نسخ المؤشر ، وليس الصفيف كله.
نصائح أخرى
قم بتشغيل الكود عبر Valgrind على جهاز Linux وستندهش من عدد الأماكن التي تتسرب من الكود الخاص بك. إذا كنت تأخذ الطريق الصعب لإدارة ذاكرتك ، فقم بذلك بشكل جيد و "حذف" جميع الذاكرة المخصصة الجديدة قبل تخصيص المزيد. إذا كنت تفضل ، من ناحية أخرى ، الطريق السهل ، استخدم ناقل STD :: ونسيان إدارة الذاكرة.
في حلقتك ، لديك هذا الخط
int max = (prevrow[i]>prevrow[i-1])?prevrow[i]:prevrow[i-1];
في التكرار الأول للحلقة الرئيسية ، متى currownum == 1
, ، سيتم إدخال الحلقة التي تحتوي على هذا الخط ، كما i
تتم تهيئته إلى 1
. ولكن في التكرار الأول ، prevrow
فقط لديه عنصر واحد ويحاول هذا الخط الوصول prevrow[1]
. في بناء التصحيح ، تتم تهيئة الذاكرة ببساطة إلى الصفر ، ولكن في البناء العادي ، تحصل على بعض قيمة القمامة التي حدثت في الذاكرة ، مما يؤدي إلى النتيجة التي تراها.
دائمًا إلى حد كبير ، عندما تحصل على قيم القمامة في البناء العادي ، ولكن كل شيء على ما يرام في بناء التصحيح ، فأنت تصل إلى بعض الذاكرة غير المألوفة.
أيضا ، البرنامج الخاص بك يتسرب الذاكرة مثل مجنون. على سبيل المثال ، لا تحتاج إلى تعيين أي نتيجة new
داخل الحلقة إلى prevrow
لأنه مباشرة بعد ذلك تتغير prevrow
للإشارة إلى كتلة أخرى من الذاكرة المخصصة. أيضا ، يجب عليك الاتصال delete
لأي ذاكرة لم تعد تستخدمها.