CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Join Date
    Dec 2017
    Posts
    41

    Two dimensional dynamic string array

    I have a 2 dimensional dynamic string array. I don't understand how to add values at the end of it

    Code:
    vector<vector<string>> str;
    vector<string> A;
    
    A.push_back("1");
    A.push_back("2");
    A.push_back("3");
    A.push_back("4");
    
    str.push_back(A);
    
    A.push_back("11");
    A.push_back("22");
    A.push_back("33");
    A.push_back("44");
    
    str.push_back(A);
    
    cout <<    str[1][3] << endl;

  2. #2
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Two dimensional dynamic string array

    Does this code compile?
    Does it work? If it does - what is the result?
    Victor Nijegorodov

  3. #3
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Two dimensional dynamic string array

    Close. What you need is to clear vector A after you have pushed it's contents to str. Otherwise vector A becomes 1 2 3 4 11 22 33 44 etc as it gets bigger with every push_back.

    Code:
    include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	vector<vector<string>> str;
    	vector<string> A;
    
    	A.push_back("1");
    	A.push_back("2");
    	A.push_back("3");
    	A.push_back("4");
    
    	str.push_back(A);
    	A.clear();
    
    	A.push_back("11");
    	A.push_back("22");
    	A.push_back("33");
    	A.push_back("44");
    
    	str.push_back(A);
    
    	cout << str[1][3] << endl;
    
    	for (const auto& s1 : str) {
    		for (const auto& s2 : s1)
    			cout << s2 << " ";
    
    		cout << endl;
    	}
    }
    which gives the expected output

    Code:
    44
    1 2 3 4
    11 22 33 44
    Or use a different variable each time for the push back.

    Code:
    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	vector<vector<string>> str;
    	vector<string> A;
    
    	A.push_back("1");
    	A.push_back("2");
    	A.push_back("3");
    	A.push_back("4");
    
    	str.push_back(A);
    
    	vector<string> B;
    
    	B.push_back("11");
    	B.push_back("22");
    	B.push_back("33");
    	B.push_back("44");
    
    	str.push_back(B);
    
    	cout << str[1][3] << endl;
    
    	for (const auto& s1 : str) {
    		for (const auto& s2 : s1)
    			cout << s2 << " ";
    
    		cout << endl;
    	}
    }
    which produces the same output
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    Dec 2017
    Posts
    41

    Re: Two dimensional dynamic string array

    Thank you

    How do I reference this in multiple cpp files and headers.

    In functions.cpp I have :


    Code:
    vector<vector<string>> str;
    vector<string> A;
    and in header.h

    Code:
    extern  vector<vector<string>> str;
    extern  vector<string> A;
    And I'm also using str in main.cpp
    Last edited by binary2; July 25th, 2018 at 04:55 PM.

  5. #5
    Join Date
    Aug 2006
    Posts
    231

    Re: Two dimensional dynamic string array

    Don't do that unless you have very good reasons. It may seem convenient to be able to access your data from any function, but it has many drawbacks. It will make your code harder to understand and reason about.

    Your first choice should be to use function parameters.

  6. #6
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Two dimensional dynamic string array

    As TabularX said, you should really avoid having any kind of global data.
    If a function or class needs certain data, you should inject the data into the function or class.
    For a function, the data becomes one of the function parameters. For a class, it can be one of the class' constructors or some setter method.
    Having global data makes it very hard to reason about your program, makes debugging harder, makes it harder to prevent unauthorized modification of the data, make unit testing difficult if not impossible, and so on.
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  7. #7
    Join Date
    Feb 2017
    Posts
    677

    Re: Two dimensional dynamic string array

    Quote Originally Posted by Marc G View Post
    As TabularX said, you should really avoid having any kind of global data.
    Only that some data is global in the sense of a Singleton.

    If you have a proper Singleton there's no obvious advantage in passing it around by way of Dependency Injection. It may even increase coupling since modules not using the Singleton may become dependent on it (because it needs to be passed through them to get to other modules that do use it).

    So in my view there's a design trade-off between using a Singleton directly or by injection. One is not always better than the other.
    Last edited by wolle; July 27th, 2018 at 04:08 AM.

  8. #8
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Two dimensional dynamic string array

    Only that some data is global in the sense of a Singleton.
    Advanced topics like this can be an exception to the rule. However another piece of advice is appropriate here.

    "Before breaking the rules, first know the rules and then why they are being broken."
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  9. #9
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Two dimensional dynamic string array

    Singleton are a kind of global data. So even for them, it's adviceable to avoid them, for example with dependency injection. That makes it easier to replace them with stubs for unit testing.
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  10. #10
    Join Date
    Feb 2017
    Posts
    677

    Re: Two dimensional dynamic string array

    Quote Originally Posted by Marc G View Post
    Singleton are a kind of global data. So even for them, it's adviceable to avoid them, for example with dependency injection. That makes it easier to replace them with stubs for unit testing.
    If you have a proper Singleton (that is data that is naturally global) you have a choice. You can either access the Singleton directly where it is needed or you can pass around the same Singleton by way of dependency injection (although you may then not call it a Singleton even though it's the same global data). In my view this is a typical design decision where you have to weight the pros and cons of each approach and that the outcome is not obvious. Here's a balanced discussion along those lines,

    https://enterprisecraftsmanship.com/...ncy-injection/
    Last edited by wolle; July 28th, 2018 at 08:46 AM.

  11. #11
    Join Date
    Feb 2017
    Posts
    677

    Re: Two dimensional dynamic string array

    Quote Originally Posted by binary2 View Post
    How do I reference this in multiple cpp files and headers.
    I here show how I would do that in modern C++ (without regard to the broader discussion of whether global data is evil or not).

    I would introduce this include file (globstrvec.h):

    Code:
    	// include guard
    #ifndef GLOBSTRVEC_ONCE
    #define GLOBSTRVEC_ONCE
    
    #include <string>
    #include <vector>
    
    namespace gsv { // global string vector namespace
    
    	inline auto& str() { // a Singleton
    		static std::vector<std::vector<std::string>> v;
    		return v;
    	}
    
    	inline auto& A() { // a Singleton
    		static std::vector<std::string> v;
    		return v;
    	}
    }
    
    #endif
    This include file can be used anywhere in a program and give access to the global data structures by way of the Singleton functions. The initialization of the static data structures is thread-safe but access to the actual data is not (so if a data structure is updated concurrently from different threads the program will crash).

    Here's how the include file can be used with the example posted by 2kaud in post #3:

    Code:
    #include "globstrvec.h"
    #include <iostream>
    
    void test() {
    
    	gsv::A().push_back("1");
    	gsv::A().push_back("2");
    	gsv::A().push_back("3");
    	gsv::A().push_back("4");
    
    	gsv::str().push_back(gsv::A());
    	gsv::A().clear();
    
    	gsv::A().push_back("11");
    	gsv::A().push_back("22");
    	gsv::A().push_back("33");
    	gsv::A().push_back("44");
    
    	gsv::str().push_back(gsv::A());
    
    	std::cout << gsv::str()[1][3] << std::endl;
    
    	for (const auto& s1 : gsv::str()) {
    		for (const auto& s2 : s1) std::cout << s2 << " ";
    		std::cout << std::endl;
    	}
    }
    Finally I agree with the general consensus that global data should be avoided (but not to the extent that they are always evil and therefore can never be preferred in any specific situation whatsoever).
    Last edited by wolle; July 28th, 2018 at 03:58 AM.

  12. #12
    Join Date
    Aug 2006
    Posts
    231

    Re: Two dimensional dynamic string array

    Quote Originally Posted by wolle View Post
    If you have a proper Singleton there's no obvious advantage in passing it around by way of Dependency Injection. It may even increase coupling since modules not using the Singleton may become dependent on it (because it needs to be passed through them to get to other modules that do use it)
    There are advantages, for example regarding unit testing.

    Coupling with a specific class can be avoided. For example, you can use a template. Or use a function as parameter (a lambda function passed as argument may access global state if needed). This way you can pass anything that fulfills the requirements of the interface, not limited to the type of your singleton.

    There is a real dependency even though you may only need to pass it through. Don't try to hide such dependencies by using a global variable (or singleton) directly and pretend there is no dependency. The code will probably become harder to maintain. A good designed system with dependency injection often doesn't need much further explanation, while on the other hand if a function modifies global state you would need to document such side effects very carefully.

    I think singletons are often overused and/or misused. The main motivation for using a singleton is to ensure that there must be exactly one instance of a class.

    I don't even remember the last time that I really needed to ensure that, but I would use it as a last resort in case it's associated with danger or malfunction if a second instance was later to be created by an oblivous programmer.
    Last edited by TubularX; July 28th, 2018 at 10:32 AM.

  13. #13
    Join Date
    Feb 2017
    Posts
    677

    Re: Two dimensional dynamic string array

    Quote Originally Posted by TubularX View Post
    I think singletons are often overused and/or misused.
    That's true of alcohol too but that shouldn't stop you from enjoying a cold beer on a hot summer day if you can handle it.

    Also dependency injection can be misused and nothing should be overused. But I rest my case here because my view is nicely expressed at the link I posted in #10. Global data should be avoided but sometimes you have it and then there are several ways to deal with it of which no one is better than the other under all circumstances.
    Last edited by wolle; July 28th, 2018 at 10:47 AM.

  14. #14
    Join Date
    Aug 2006
    Posts
    231

    Re: Two dimensional dynamic string array

    But I rest my case here because my view is nicely expressed at the link I posted in #10
    Well, the advice from your link says:

    "If a dependency is ambient, meaning that it is used by many classes and/or multiple layers, use Singleton."

    I just don't think it's that simple. That may be feasible when there's one way communication with the singleton, for example a simple logger service that you only append to, or a configuration that you only read from.

    But otherwise, it's going to be a struggle to maintain in a complex system. In a simple application you may be able to handle it with ease, but then it's probably overkill to use singletons anyway.

    With dependency injection in C++ you can also use const correctness so that it is clear when data is modified or not.

    Global data should be avoided but sometimes you have it and then there are several ways to deal with it of which no one is better than the other under all circumstances.
    I agree with that part.
    Last edited by TubularX; July 28th, 2018 at 11:19 AM.

  15. #15
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Two dimensional dynamic string array

    My take on this as in post #8. The rule should be to avoid global data. However, when you know the rules then there are cases when the rules can be broken - because you know you are breaking them and the consequences. If a rule is broken then why, how etc should be justified and documented. 'because it's easiest' isn't a justification!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured