2016-04-08 11 views
6

में गतिशील दो आयामी सरणी आरंभ करने के लिए मेमसेट या fill_n का उपयोग कैसे करें मेरे पास 2 डी सरणी गतिशील रूप से बनाई गई है।सी ++

int **abc = new int*[rows]; 

for (uint32_t i = 0; i < rows; i++) 
{ 
    abc[i] = new int[cols]; 
} 

मैं सरणी को कुछ मूल्य (1 कहें) भरना चाहता हूं। मैं प्रत्येक आइटम पर लूप कर सकता हूं और इसे कर सकता हूं।

लेकिन क्या कोई आसान तरीका है। मैं और std::fill_n का उपयोग करने की कोशिश कर रहा हूं जैसा कि this post में उल्लिखित है।

std::fill_n(abc, rows * cols, 1); 
memset(abc, 1, rows * cols * sizeof(int)); 

मेमसेट का उपयोग करना मेरे प्रोग्राम को क्रैश करता है। Fill_n का उपयोग एक संकलन त्रुटि देता है।

invalid conversion from 'int' to 'int*' [-fpermissive] 

मैं यहां क्या गलत कर रहा हूं?

+0

वापस सेल्सियस तक गिराने के लिए एक विकल्प हो सकता है: 'int (* abc) [cols] = malloc (पंक्तियां * आकार (* एबीसी)); मेमसेट (एबीसी, 1, पंक्तियां * आकार (* एबीसी)); सी 99 के बाद से कानूनी सी है, लेकिन जल्द ही सी ++ में संभव नहीं होगा। – cmaster

उत्तर

5

तुम बस vector इस्तेमाल कर सकते हैं:

std::vector<std::vector<int>> abc(rows, std::vector<int>(cols, 1)); 

आप abc पर std::fill_n या memset उपयोग नहीं कर सकते सीधे, यह बस काम नहीं करेगा। आप केवल उप-सरणियों पर भी उपयोग कर सकते हैं:

int **abc = new int*[rows]; 

for (uint32_t i = 0; i < rows; i++) 
{ 
    abc[i] = new int[cols]; 
    std::fill_n(abc[i], cols, 1); 
} 

या पूरी बात एक आयामी बनाने:

int *abc = new int[rows * cols]; 
std::fill_n(abc, rows*cols, 1); 

या मैं आप std::fill_n के साथ संयोजन में std::generate_n इस्तेमाल कर सकते हैं लगता है, लेकिन यह सिर्फ लगता है भ्रामक:

int **abc = new int*[rows]; 
std::generate_n(abc, rows, [cols]{ 
    int* row = new int[cols]; 
    std::fill_n(row, cols, 1); 
    return row; 
}); 
+1

@NathanOliver धन्यवाद! – Barry

3

मुझे लगता है कि अपने मुख्य समस्या यह है कि यहाँ आप int मूल्यों की एक सरणी की जरूरत नहीं है है। आपके पास int एस के पॉइंटर्स की एक सरणी है।

आपको शायद int* abc = new int[rows * cols]; से शुरू करना चाहिए और वहां से काम करना चाहिए, अगर मैं समझता हूं कि आप यहां क्या हासिल करने की कोशिश कर रहे हैं।

2

बस पाश आपके पास पहले से अंदर के साथ प्रयोग *:

for (uint32_t i = 0; i < rows; i++) 
{ 
    abc[i] = new int[cols]; 
    std::fill_n(*(abc+i), cols, sizeof(int)); 
} 

fill_n पता नहीं है जहां स्मृति नई पूर्णांक सरणी नक्शे, तो आप ध्यान से इस तरह से कोडिंग होना चाहिए।

मैं पढ़ने के लिए सलाह देते हैं: छोड़ दिया और A proper way to create a matrix in c++

1

के बाद से आप पहले से ही अपनी समस्या को हल करने के लिए अच्छा है, व्यावहारिक जवाब मिल गया है, मैं सिर्फ दो संकेत जोड़ना चाहते हैं सही मानक पथ ;-)

से

क) Boost.MultiArray

के दस्तावेजीकरण करने के लिए सिर्फ एक कड़ी है और ख) मैं तुम्हें का उपयोग की सलाह नहीं देते , लेकिन यह आप को समझने के लिए क्या आप शुरू में की कोशिश की है मदद कर सकता है कुछ है। और चूंकि आपकी प्रोफ़ाइल visual studio टैग दिखाती है, तो आप Win32 api में इस तरह के संपर्क में आ सकते हैं। यदि ऐसा होता है तो दस्तावेज़ आमतौर पर आपको तत्वों और "बाहरी" सूचक-सूचक पर मुफ्त()/LocalFree()/... का उपयोग नहीं करने के लिए कहता है लेकिन एक विशेष कार्य का उपयोग करने के लिए।
(ध्यान दें: मैं इस कोड बनाने की कोशिश कर नहीं कर रहा हूँ सुंदर या चालाक लग रही है, यह ग की एक उलझन और एक छोटे से C++ है - ish कबाड़ ;-))

const std::size_t rows = 3, cols =4; 

int main() 
{ 
    std::size_t x,y; 
    // allocate memory for 0...rows-1 int* pointers _and_ cols*rows ints 
    int **abc = (int**)malloc((rows*sizeof(int*)) + cols*rows*sizeof(int)); 

    // the memory behind abc is large enough to hold the pointers for abc[0...rows-1] 
    // + the actual data when accessing abc[0...rows-1][0....cols-1] 
    int* data = (int*)((abc+rows)); 
    // data now points to the memory right after the int*-pointer array 
    // i.e. &(abc[0][0]) and data should point to the same location when we're done: 
    // make abc[0] point to the first row (<-> data+(cols*0)), abc[1] point the second row (<-> data+(cols*1).... 
    for(y=0;y<rows; y++) { 
     abc[y] = &(data[y*cols]); 
    } 

    // now you can use abc almost like a stack 2d array 
    for(y=0; y<rows; y++) { 
     for (x=0; x<cols; x++) { 
      abc[y][x] = 127; 
     } 
    } 

    // and -since the memory block is continuos- you can also (with care) use memset 
    memset(&abc[0][0], 1, sizeof(int)*rows*cols); 

    // and with equal care .... 
    std::fill_n(&(abc[0][0]), rows*cols, 127); 

    // and get rid of the whole thing with just one call to free 
    free(abc); 

    return 0; 
}