Content DB Attach using PowerShell


In this post, I’ll talk about how to attach\mount a SharePoint content database to a SharePoint web application after it has been restored\attached to the SQL server. See my previous post for details on how to restore a database using PowerShell.

SharePoint provides a cmdlet to do the content db attach. This cmdlet is called Mount-SPContentDatabase. I will create a script block wrapper for this cmdlet and show how to call it remotely. The script block below adds the SharePoint PowerShell snapin if it’s not already added, selects a web application in the farm, then calls the Mount-SPContentDatabase to do the content db attach.

[ScriptBlock] $global:AttachSPContentDB =
{
    param([string] $dbName, [string] $dbServer)

    try
    {
        # Load the Sharepoint Cmdlets
        Write-Host "Loading SharePoint PowerShell Snapin"
        $spSnapin = Get-PSSnapin | where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}
        if($spSnapin -eq $null)
        {
            Add-PSSnapin Microsoft.SharePoint.PowerShell
            Write-Host -ForegroundColor "Green" -Object "SharePoint PowerShell Snapin loaded"
        }
        else
        {
            Write-Host -ForegroundColor "Gray" -Object "SharePoint PowerShell Snapin already loaded"
        }

        # Get  web applciation url
        Write-Host "Selecting a web application in the farm"
        $webAppUrl = (Get-SPWebApplication | select -Index 0).Url

        # Mount the database at the specified SQL server to the web application
        Write-Host "Mounting database '$dbName' at SQL server '$dbServer' to web application '$webAppUrl'"
        $newDB = Mount-SPContentDatabase $dbName -DatabaseServer $dbServer -WebApplication $webAppUrl -AssignNewDatabaseId
        Write-Host -ForegroundColor "Green" -Object "Database mounted successfully with ID: " + ($newDB.Id)

        # Return content DB Id
        return $newDB.Id.ToString()
    }
    catch [Exception]
    {
        Write-Host -ForegroundColor "Red" -Object $_.Exception

        return $null
    }
}

To call this script block, pass the name of the Sql server and the name of the content database. Make sure that the content database is already restored\attached to the SQL server.

.$AttachSPContentDB "ContentDBName" "SqlServerName"

To call the script block on a remote SharePoint WFE, you can simply run

Invoke-Command -ComputerName "WFEName" -ScriptBlock { .$AttachSPContentDB "ContentDBName" "SqlServerName" }

Note that the New-SPContentDatabase cmdlet has the same effect as Mount-SPContentDatabase. The only difference is that New-SPContentDatabase creates a new SQL database if there is no database with the same name already available on the SQL server.

SQL DB Restore using PowerShell


If you are looking for a PowerShell script that lets you restore a database from a backup (.bak) file to MSSQL server, then this is the right place for you.

Database Restore – SQL

Let’s say you have a .bak file (Ex: AdventureWorks), and you would like to restore it to an SQL server using PowerShell. If you use SQL Server 2008 Management Studio and click on the “Script” button, you will get th SQL statement that will do that restore for you.

Here is the SQL RESTORE statement that will allow you to restore the AdventureWorksLT2008R2.bak to the new database ‘NewDatabaseName’.

RESTORE DATABASE [NewDatabaseName]
FROM DISK = N'C:\.etc..\AdventureWorksLT2008R2.bak'
WITH FILE = 1,
MOVE N'AdventureWorksLT2008R2_Data'
TO N'C:\.etc..\MSSQL\DATA\NewDatabaseName.mdf',
MOVE N'AdventureWorksLT2008R2_Log'
TO N'C:\.etc..\MSSQL\DATA\NewDatabaseName_1.ldf',
NOUNLOAD, STATS = 10

If you use SQL Server 2008 R2 Management Studio, the generated SQL statement would look like this.

RESTORE DATABASE [NewDatabaseName]
FROM  DISK = N'C:\.etc..\AdventureWorksLT2008R2.bak'
WITH  FILE = 1,  NOUNLOAD,  STATS = 10

Running this statement is almost the same as the previous statement, except that the MDF and LDF files would be named AdventureWorksLT2008R2_Data.mdf and AdventureWorksLT2008R2_Log.ldf respectively (instead of having NewDatabaseName in the file names).

If we want to create a simple PowerShell function to run the SQL Restore command, we can do so using the OSQL Utility:

function global:RestoreDB ([string] $newDBName, [string] $backupFilePath)
{
    [string] $dbCommand = "RESTORE DATABASE [$newDBName] " +
    "FROM    DISK = N'$backupFilePath' " +
    "WITH    FILE = 1, NOUNLOAD, STATS = 10"

    OSQL.EXE -E -Q $dbCommand
}

We can also take advantage of the Invoke-Sqlcmd command to do the same thing. Here is how the function would look like:

function global:RestoreDB ([string] $newDBName, [string] $backupFilePath)
{
    [string] $dbCommand = "RESTORE DATABASE [$newDBName] " +
                          "FROM    DISK = N'$backupFilePath' " +
                          "WITH    FILE = 1, NOUNLOAD, STATS = 10"

    Invoke-Sqlcmd -Query $dbCommand
}

If using Invoke-Sqlcmd fails, make sure the SqlServerCmdletSnapin100 snapin is added. You can put the below snippet in the function above before the call to Invoke-Sqlcmd.

$sqlSnapin = Get-PSSnapin | where {$_.Name -eq "SqlServerCmdletSnapin100"}
if($sqlSnapin -eq $null)
{
Add-PSSnapin SqlServerCmdletSnapin100
}

Calling this function is as simple as:

RestoreDB "NewDatabaseName" "C:\.etc..\AdventureWorksLT2008R2.bak"

Remote SQL Server

In case your SQL Server is on a remote machine that doesn’t have the SQL client installed, you can use the Invoke-Command to restore the database on the remote machine. However, the function needs to be loaded to be invoked on the remote machine, so either put it in a separate file and load it remotely or convert it to a script block that can be directly passed to Invoke-Command.

Assuming the remote SQL server name is SQLServer01, here are the two approaches to do this.

Using a Function

Put the RestoreDB function in a new PowerShell file; Let’s call it DatabaseRestore.ps1. To call remotely, first we need to create a PowerShell session on the remote SQL Server machine.

$session = New-PSSession -ComputerName "SQLServer01"

If you are using SQL Server 2008 R2, you might get the following error: “Connecting to remote server failed with the following error message : The WinRM client cannot complete the operation within the time specified. Check if the machine name is valid and is reachable over the network and firewall exception for Windows Remote Management service is enabled“. The resolution is located here. In short, go to your SQL Server 2008 R2 machine, launch the Command Prompt as administrator then run this command: winrm quickconfig.

After creating the session, we need to load the DatabaseRestore.ps1 script on the remote machine to be able to call the RestoreDB function.

$scriptPath = "C:\..etc..\DatabaseRestore.ps1"
Invoke-Command -Session $session -FilePath $scriptPath

If you get an error that the file cannot be loaded because the execution of scripts is disabled on the system, then you should make sure that the execution policy is remotesigned or unrestricted (Set-ExecutionPolicy unrestricted).

Next step would be to simply call the function. Note that the path to the backup file must be accessible to the remote SQL machine.

Invoke-Command -Session $session -ScriptBlock { RestoreDB "NewDatabaseName" "C:\..etc..\AdventureWorksLT2008R2.bak" }
Using a Script Block

In our case, using a script block is simpler. All we need to do is define the script block, then run one single Invoke-Command to do the database restore. The script block definition is almost the same as the function definition, as shown below:

[ScriptBlock] $global:RestoreDB = {

    param ([string] $newDBName, [string] $backupFilePath)

    [string] $dbCommand = "RESTORE DATABASE [$newDBName] " +
                          "FROM    DISK = N'$backupFilePath' " +
                          "WITH    FILE = 1, NOUNLOAD, STATS = 10"

    $sqlSnapin = Get-PSSnapin | where {$_.Name -eq "SqlServerCmdletSnapin100"}
    if($sqlSnapin -eq $null)
    {
         Add-PSSnapin SqlServerCmdletSnapin100
    }

    Invoke-Sqlcmd -Query $dbCommand
}

Make sure you don’t forget the equal sign (=) in the first line of the above script block definition. Now, to restore the DB, we call a single Invoke-Command cmdlet. Make sure that the -ArgumentList parameters are separated by comma (,) or the script will fail.

Invoke-Command -ComputerName "SQLServer01" -ScriptBlock $RestoreDB -ArgumentList "NewDatabaseName", "C:\AdventureWorksLT2008R2.bak" 
Function vs. Script Block

Here are some simple guidelines on when to use a function and when to use a script block.

  • To call a function on a remote machine, it must first be defined on the remote machine. That’s why we need an Invoke-Command to load the PowerShell file containing the function, then another Invoke-Command to call the function.
  • To call a script block remotely, it doesn’t have to be defined on the remote machine. When the script block is passed as a parameter to Invoke-Command, the whole script block actually gets copied to the remote machine.
  • If your logic has any dependency on any global variable or function (Ex: it calls another script block or it calls a helper function), then it makes most sense to use a function. Define the function, global variables and helper functions in one file, then load them on the remote machine.
  • If your logic is self-contained, then use a script block. The whole logic will get copied to the remote machine.

Database Restore – SMO

To have more control on how we do the database restore, we should use the SMO object model. For example, our script above restores the database with name “NewDatabaseName” but the MDF and LDF file names are still AdventureWorksLT2008R2_Data.mdf and AdventureWorksLT2008R2_Log.ldf. Now, you would think, why not use the SQL statement below in our script?

RESTORE DATABASE [NewDatabaseName]
FROM DISK = N'C:\.etc..\AdventureWorksLT2008R2.bak'
WITH FILE = 1,
MOVE N'AdventureWorksLT2008R2_Data'
TO N'C:\.etc..\MSSQL\DATA\NewDatabaseName.mdf',
MOVE N'AdventureWorksLT2008R2_Log'
TO N'C:\.etc..\MSSQL\DATA\NewDatabaseName_1.ldf',
NOUNLOAD, STATS = 10

To put this in a script block, it will look as follows:

[ScriptBlock] $global:RestoreDB = {

param ([string] $newDBName, [string] $backupFilePath, [string] $sqlDataPath, [string] $dataLogicalName, [string] $logLogicalName)

[string] $dbCommand = "RESTORE DATABASE [$newDBName] " +
"FROM    DISK = N'$backupFilePath' " +
"WITH    FILE = 1, " +
"MOVE N'$dataLogicalName' " +
"TO N'$sqlDataPath\$newDBName.mdf', " +
"MOVE N'$logLogicalName' " +
"TO N'$sqlDataPath\$newDBName.ldf', " +
"NOUNLOAD, STATS = 10"

$sqlSnapin = Get-PSSnapin | where {$_.Name -eq "SqlServerCmdletSnapin100"}
if($sqlSnapin -eq $null)
{
Add-PSSnapin SqlServerCmdletSnapin100
}

Invoke-Sqlcmd -Query $dbCommand
}

Ok, this might be good enough, but it’s not dynamic\generic. You can get the SQL data path from the registry, but you cannot get the logical names of the data and log files unless you find a way to open the .bak file and read the logical names of those files. Instead of hardcoding the logical names of the Data and Log files (i.e. pass “AdventureWorksLT2008R2_Data” and “AdventureWorksLT2008R2_Log”), we can read the file list from the .bak file using SMO (ReadFileList() method).

PowerShell comments below provide enough details. Note that if the backup file is on a network share, the ReadFileList() method would fail. So in that case, we need to copy the file locally. That’s why the script block takes “$isNetworkPath” boolean variable to take that into consideration.

[ScriptBlock] $global:RestoreDBSMO = {
    param([string] $newDBName, [string] $backupFilePath, [bool] $isNetworkPath = $true)

    try
    {
        # Load assemblies
        [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
        [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
        [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
        [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

        # Create sql server object
        $server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"

        # Copy database locally if backup file is on a network share
        if($isNetworkPath)
        {
            $fileName = [IO.Path]::GetFileName($backupFilePath)
            $localPath = Join-Path -Path $server.DefaultFile -ChildPath $fileName
            Copy-Item $backupFilePath $localPath
            $backupFilePath = $localPath
        }

        # Create restore object and specify its settings
        $smoRestore = new-object("Microsoft.SqlServer.Management.Smo.Restore")
        $smoRestore.Database = $newDBName
        $smoRestore.NoRecovery = $false;
        $smoRestore.ReplaceDatabase = $true;
        $smoRestore.Action = "Database"

        # Create location to restore from
        $backupDevice = New-Object("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFilePath, "File")
        $smoRestore.Devices.Add($backupDevice)

        # Give empty string a nice name
        $empty = ""

        # Specify new data file (mdf)
        $smoRestoreDataFile = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
        $defaultData = $server.DefaultFile
        if (($defaultData -eq $null) -or ($defaultData -eq $empty))
        {
            $defaultData = $server.MasterDBPath
        }
        $smoRestoreDataFile.PhysicalFileName = Join-Path -Path $defaultData -ChildPath ($newDBName + "_Data.mdf")

        # Specify new log file (ldf)
        $smoRestoreLogFile = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
        $defaultLog = $server.DefaultLog
        if (($defaultLog -eq $null) -or ($defaultLog -eq $empty))
        {
            $defaultLog = $server.MasterDBLogPath
        }
        $smoRestoreLogFile.PhysicalFileName = Join-Path -Path $defaultLog -ChildPath ($newDBName + "_Log.ldf")

        # Get the file list from backup file
        $dbFileList = $smoRestore.ReadFileList($server)

        # The logical file names should be the logical filename stored in the backup media
        $smoRestoreDataFile.LogicalFileName = $dbFileList.Select("Type = 'D'")[0].LogicalName
        $smoRestoreLogFile.LogicalFileName = $dbFileList.Select("Type = 'L'")[0].LogicalName

        # Add the new data and log files to relocate to
        $smoRestore.RelocateFiles.Add($smoRestoreDataFile)
        $smoRestore.RelocateFiles.Add($smoRestoreLogFile)

        # Restore the database
        $smoRestore.SqlRestore($server)

        "Database restore completed successfully"
    }
    catch [Exception]
    {
        "Database restore failed:`n`n " + $_.Exception
    }
    finally
    {
        # Clean up copied backup file after restore completes successfully
        if($isNetworkPath)
        {
            Remove-Item $backupFilePath
        }
    }
}

Here is how to call this script block (Don’t forget the dot (.) infront of the script block variable):

.$RestoreDBSMO "NewDatabaseName" "C:\.etc..\AdventureWorksLT2008R2.bak" $false

Same story goes for calling this function remotely.

SharePoint Foundation 2010 on Windows 7


This MSDN article describes in detail how to install SharePoint Foundation 2010 for development purposes on Windows Vista, Windows 7 and Windows Server 2008. The purpose of this post is to focus on the SharePoint installation on Window 7 only and clear out all the details for the other operating systems.

  1. Download SharePoint Foundation 2010 x64 for free. Note that there is no x86 version of SharePoint Server, so don’t bother setting it up if you have a 32-bit machine.
  2. Create a new folder “C:\SharePointFiles” and copy “SharePointFoundation.exe” to it.
  3. Start command prompt, change directory to C:\SharePointFiles and run the following command to extract the “SharePointFoundation.exe” to C:\SharePointFiles
    SharePointFoundation.exe /extract:C:\SharePointFiles
  4. Open C:\SharePointFiles\files\Setup\config.xml, add a new <Setting> tag under the <Configuration> element, then save the file. Make sure you copy the below element as is since all of the text in the configuration file is case-sensitive.
    <Setting Id=”AllowWindowsClientInstall” Value=”True”/>
  5. Install the following Prerequisites:
  6. Enable the required windows features by running this batch file: http://cid-e38f9fc6490b29d9.skydrive.live.com/self.aspx/Public/Scripts/EnableSPWinFeatures.bat
  7. Restart your computer to complete the changes that you made to Windows Features.
  8. Install SharePoint 2010
    • Run Setup.exe under C:\SharePointFiles
    • Select standalone (Windows 7 can’t be used for production deployments of SharePoint 2010 and it’s recommended that you use Standalone only)
    • After the installation is complete, you will be prompted to start the SharePoint Products and Technologies Configuration Wizard.
      InstallSP
  9. After a SharePoint solution (.wsp file) is deployed, it recycles the application pool. To improve the initial page load times, set the optimizeCompilations property of the <compilation> tag in your web.config file (C:\inetpub\wwwroot\wss\VirtualDirectories\80\web.config) to true.
    <compilation optimizeCompilations=”true”>

SharePoint Designer 2010 is also free and can help you better design your SharePoint site(s). You can download it here.

OpenGL Camera


The concept of a camera in a Graphics application is simple. Just imagine that what you see is the view of the camera. So adjusting the camera lens or moving\rotating it should affect your view. In the base OpenGL library, there is no concept of a camera. However, it can be simulated by applying the inverse of the camera transformation on the objects\pixels in the scene. Instead of having to build the matrix and invert it ourselves, the GLU library provides the gluLookAt function, which would do the work for us. This function takes as a parameter the location (x, y, z) of the camera\eye, the location (x, y, z) of the point to look at, and the coordinates (x, y, z) of the Up vector (rotation of the camera around its origin). Note that this function should be called on the ModelView matrix before any transformation is applied on objects in the scene. Avoid calling this function on the Projection matrix (more details here).

Given the description above, after specifying the camera attributes with a call to gluLookAt then drawing the objects in the scene, one would expect to see the objects in the scene based on the view of the camera. This expectation is completely valid, however, there is one more variable that affects what we see: the viewing volume (similar to real-world camera focus), which is controlled by calls on the projection matrix. Try to imagine what you’ll see if you run the code below:

GLdouble eyeX = 0, eyeY = 0, eyeZ = 2;
GLdouble centerX = 0, centerY = 0, centerZ = 0;
GLdouble upX = 0, upY = 1, pZ = 0;

void display()
{
    //  Set up camera properties
    glMatrixMode (GL_MODELVIEW);
    gluLookAt (eyeX, eyeY, eyeZ,
               centerX, centerY, centerZ,
               upX, upY, upZ);

    //  Draw an Object at the origin
    drawObject ();
}

The answer to the question above is that you’ll see nothing! The reason is that eyeZ = 2, the viewing volume is glOrtho(-1, 1, -1, 1, -1, 1) by default, and the object is drawn at the origin. Here is a visual demonstration using Nate Robin’s interactive OpenGL tutorial (projection.exe).

If we change zFar (last parameter of glOrtho) of projection to 3 or if we change eyeZ of the camera to 0.5, then we’ll be able to see the object.

To summarize all of this, I am taking advantage of one of the slides of the Siggraph OpenGL tutorial.

If you’ve used one of those 3D modeling software out there (like 3ds Max, Maya, etc…), then you’ve certainly seen multiple orthogonal views (Front, Back, Top, Bottom, Left, Right) of your 3D drawing. Here is a screenshot from 3ds Max.

Using the OpenGL camera, I’m going to create an OpenGL app that has 6 sub-windows each displaying the same object, but from a different camera angle. The world coordinates will be glOrtho(-1, 1, -1, 1, -2, 2) and the views will be: Front, Back, Top, Bottom, Left, and Right. The parameters that are going to be passed to gluLookAt will vary based on the view:

The program looks as follows.

Note that you can use the left mouse button to rotate the object, right mouse button to translate the object, and middle mouse button to scale it. Also, the ‘r’ key will reset the object transformations in the scene. You can find the full source code on my GitHub page. If you have any issues compiling or running the app, check out this blog post for details about compiling and running an OpenGL app that uses the GLUT library.

GLUT Menu World


This post demonstrates how to create a GLUT menu and add to it sub-menus and menu items.

In the above sample app, clicking on a menu item in the popup menu will log that menu item’s ID to the console window. Below is the function setupMenus() that creates the main menu and adds to it all the sub-menus and menu items. You can change it based on your needs then call it in the init() method.

//-------------------------------------------------------------------------
//  Set up the GLUT Menus.
//-------------------------------------------------------------------------
void setupMenus ()
{
    int subMenuCount;  //  Count of sub menus
    int menuItemCount; //  Count of menu items in a submenu
    int *menuIds;      //  Submenu IDs
    char str[256];     //  The string of the current menu item
    int i, j;          //  Iterators

    //  Generate a random value for submenu count
    subMenuCount = rand() % 20;

    //  Allocate memory for the submenu IDs
    menuIds = (int *) xmalloc (subMenuCount * sizeof (int));

    //  Create all the sub menus
    for (i = 0; i < subMenuCount; i++)
        menuIds[i] = glutCreateMenu (showMenuItem);

    for (i = 1; i < subMenuCount; i++)
    {
        //  Set sub menu string
        sprintf (str, "SubMenu %d", i);

        //  Add the current submenu to previous submenu
        glutSetMenu (menuIds[i-1]);
        glutAddSubMenu (str, menuIds[i]);

        //  New menu item count for the new submenu
        menuItemCount = rand () % 20;

        //  Add menu items to the current submenu
        for (j = 1; j < menuItemCount; j++)
        {
            sprintf (str, "Menu Item %d", j);
            glutAddMenuEntry (str, j);
        }
    }

    //  Set main menu as the current menu
    glutSetMenu (menuIds[0]);

    //  Attach the menu to the RMB
    glutAttachMenu(GLUT_RIGHT_BUTTON);
}

Major GLUT functions briefly explained:

  • glutCreateMenu creates the main menu or sub-menu and returns its ID. It takes as a parameter a pointer to a function with the signature void func (int menuItemId). This function is called every time the  user clicks a menu item in the menu and the parameter menuItemId passed to it represents the id of the menu item.
  • glutAddSubMenu adds another menu to current menu.
  • glutAddMenuEntry adds a menu item to the current menu.
  • glutSetMenu sets the current menu. So when we call glutAddSubMenu or glutAddMenuEntry, they get added to the current menu.
  • glutAttachMenu(GLUT_RIGHT_BUTTON) attaches the “current” menu to the right click button. So when you right click the mouse, the popup menu will show up.

This is the function that we are passing to glutCreateMenu in our sample app. Every time the user clicks on a menu item, this function is called and it will simply display the menu item id on the console window.

//-------------------------------------------------------------------------
//  Displays the menu item id on the console window
//-------------------------------------------------------------------------
void showMenuItem (int val)
{
    printf ("Menu Item: %d\n", val);
}

Download the full source code on my GitHub page.

Dynamic Three Dimensional Arrays in C\C++\C#\Java


If you come from a Java or C# perspective and want to create a multi-dimensional array in C or C++, you’ll soon figure out that multi-dimensional array allocation in C\C++ is not as simple, plus you’ll have to worry about deallocation since there is no garbage collector to do the work for you. Below I’ll show four different sample codes showing how to work with a three dimensional array in Java, C#, C++ and C, respectively.

Java 3D Array

In Java, creating a 3-dimensional array is as simple as saying

int[][][] array3D = new int[x][y][z];

You can then access the elements of the 3-dimensional array at array3D[i][j][k].

Sample Code

public static void main(String[] args)
{
    //  Array 3 Dimensions
    int x = 4, y = 5, z = 6;

    //  Array Iterators
    int i, j, k;

    //  Allocate 3D Array
    int[][][] array3D = new int[x][y][z];

    //  Access array elements
    for (i = 0; i < x; i++)
    {
        System.out.println(i);

        for (j = 0; j < y; j++)
        {
            System.out.println();

            for (k = 0; k < z; k++)
            {
                array3D[i][j][k] = (i * y * z) + (j * z) + k;
                System.out.print("\t" + array3D[i][j][k]);
            }
        }

        System.out.println('\n');
    }
}

C# 3D Array

In C#, the concept is almost the same as in Java. However, C# makes the distinction between jagged and multi-dimensional arrays. Elements of a multi-dimensional array are stored in a contiguous block in memory while elements of a jagged array are not. Java arrays are actually jagged arrays, while C# supports both and allows you to choose which one you want based on the syntax of your code. Note that multi-dimensional arrays are better (in most cases) than jagged arrays, and that is considered a minus point for Java.

Using jagged arrays in C# is not as simple as in Java. It’s almost like the way we would implement it in C++.

int[][] jaggedArray = new int[2][];
jaggedArray[0] = new int[4];
jaggedArray[1] = new int[3];

However, multi-dimensional arrays in C# are very simply to use. You can create a 3 dimensional array as follows

int[,,] array3D = new int[x, y, z];

then access its elements at array3D[i][j][k].

Sample Code

static void Main(string[] args)
{
    //  Array 3 Dimensions
    int x = 4, y = 5, z = 6;

    //  Array Iterators
    int i, j, k;

    //  Allocate 3D Array
    int[,,] array3D = new int[x, y, z];

    //  Access array elements
    for (i = 0; i < x; i++)
    {
        Console.WriteLine(i);

        for (j = 0; j < y; j++)
        {
            Console.WriteLine();

            for (k = 0; k < z; k++)
            {
                array3D[i, j, k] = (i * y * z) + (j * z) + k;
                Console.Write("\t{0}", array3D[i, j, k]);
            }
        }

        Console.WriteLine('\n');
    }
}

C++ 3D Array

To create a multi-dimensional array in C++, we should change perspective a little bit and think of creating arrays that point to other arrays, which point to other arrays, and so on. For example, to create a 2x3x4 array in C++, we should imagine the implementation as follows:

For simplicity, we are doing the jagged implementation of the multi-dimensional array (address of array3d[0][1][0] is not directly after array3d[0][0][3] in memory representation above). In the next section, we will implement it in C the contiguous way. To allocate a jagged 2D array in C++, one can write the following (compare to C# jagged above):

int** jaggedArray = new int*[2];
jaggedArray[0] = new int[4];
jaggedArray[1] = new int[3];

The elements can be accessed as usual: jaggedArray[i][j]. The extra work we have to do in C++ is to explicitly deallocate the array.

delete[] jaggedArray[0];
delete[] jaggedArray[1];
delete[] jaggedArray;

See the code sample below to understand how we allocate and deallocate a 3 dimensional array in C++.

Sample Code

#include <iostream>

using namespace std;

void main()
{
    //  Array 3 Dimensions
    int x = 4, y = 5, z = 6;

    //  Array Iterators
    int i, j, k;

    //  Allocate 3D Array
    int ***array3D = new int**[x];

    for(i = 0; i < x; i++)
    {
        array3D[i] = new int*[y];

        for(j = 0; j < y; j++)
        {
            array3D[i][j] = new int[z];
        }
    }

    //  Access array elements
    for(i = 0; i < x; i++)
    {
        cout << i << endl;

        for(j = 0; j < y; j++)
        {
            cout << endl;

            for(k = 0; k < z; k++)
            {
                array3D[i][j][k] = (i * y * z) + (j * z) + k;
                cout << '\t' << array3D[i][j][k];
            }
        }

        cout << endl << endl;
    }

    //  Deallocate 3D array
    for(i = 0; i < x; i++)
    {
        for(j = 0; j < y; j++)
        {
            delete[] array3D[i][j];
        }

        delete[] array3D[i];
    }
    delete[] array3D;
}

C 3D Array

Implementing multi-dimensional arrays in C is very similar to C++, except that we use malloc()\free()  stdlib methods instead of the new\delete keywords. The memory representation below is the same, but we are going to focus in this section on making the elements of the 3 dimensional array contiguous.

To do so, we start by allocating space for all array elements in one call to malloc.

int *allElements = malloc(x * y * z * sizeof(int));

Next, we create the arrays of pointers, and point to the contiguous elements we’ve already allocated.

int ***array3D = malloc(x * sizeof(int **));
for(i = 0; i < x; i++)
{
    array3D[i] = malloc(y * sizeof(int *));

    for(j = 0; j < y; j++)
    {
        array3D[i][j] = allElements + (i * y * z) + (j * z);
    }
}

Note that if we wanted the same jagged implementation as in the C++ example above, we could ignore the allocation of allElements and change the line of code array3D[i][j] = allElements + (i * y * z) + (j * z); to array3D[i][j] = malloc(z * sizeof(int)). Below is a sample code for allocating, accessing and deallocating a 3 dimensional array in C.

#include <stdio.h>
#include <stdlib.h>

void main()
{
    //  Array 3 Dimensions
    int x = 4, y = 5, z = 6;

    //  Array Iterators
    int i, j, k;

    //  Allocate 3D Array
    int *allElements = malloc(x * y * z * sizeof(int));
    int ***array3D = malloc(x * sizeof(int **));

    for(i = 0; i < x; i++)
    {
        array3D[i] = malloc(y * sizeof(int *));

        for(j = 0; j < y; j++)
        {
            array3D[i][j] = allElements + (i * y * z) + (j * z);
        }
    }

    //  Access array elements
    for(i = 0; i < x; i++)
    {
        printf("%d\n", i);

        for(j = 0; j < y; j++)
        {
            printf("\n");

            for(k = 0; k < z; k++)
            {
                array3D[i][j][k] = (i * y * z) + (j * z) + k;
                printf("\t%d", array3D[i][j][k]);
            }
        }

        printf("\n\n");
    }

    //  Deallocate 3D array
    free(allElements);
    for(i = 0; i < x; i++)
    {
        free(array3D[i]);
    }
    free (array3D);
}

Source Code

Full source code for the above 4 samples is available on my GitHub page.

C Pointer Tricks


I’ve been exploring\reading more about C pointers (mostly from this source) and I’ve found the following interesting tricks.

Trick 1 – Pointer Arithmetics

Question

What is the result of running the following code?

void trick1()
{
    int arr[] = {1, 2, 3};
    int *ptr;

    ptr = arr;

    printf("arr[0] = %d, arr[1] = %d, arr[2] = %d, ptr = %p, *ptr = %d\n",
            arr[0], arr[1], arr[2], ptr, *ptr);
    *ptr++ = -1;
    printf("arr[0] = %d, arr[1] = %d, arr[2] = %d, ptr = %p, *ptr = %d\n",
            arr[0], arr[1], arr[2], ptr, *ptr);
    *++ptr = -2;
    printf("arr[0] = %d, arr[1] = %d, arr[2] = %d, ptr = %p, *ptr = %d\n",
            arr[0], arr[1], arr[2], ptr, *ptr);
    (*ptr)++;
    printf("arr[0] = %d, arr[1] = %d, arr[2] = %d, ptr = %p, *ptr = %d\n",
            arr[0], arr[1], arr[2], ptr, *ptr);
}

Solution

  • ptr = arr
    • This will make the pointer ptr point to the first element in the array arr.
  • *ptr++ = -1
    • There are two operators (* and ++) to be applied on a single operand (ptr). We have to know which one takes precedence. The answer is that the post-increment (++) will be applied first. Once it’s applied, it will not affect the value of ptr until the statement completes execution.  So as we are evaluating the current statement, ptr is still pointing to the first element of the array (arr[0]). Now, we apply the * operator to the ptr operand. This will dereference the pointer and will let us access the content it points to. Since it’s pointing to arr[0], *ptr = -1 will set the value of arr[0] to -1. After the statement completes execution, the pointer ptr is incremented and thus will point to the next element in the array (arr[1]).
  • *++ptr = -2
    • As we mentioned previously, the increment operator (++) takes precedence over the dereference operator (*). Since this is a pre-increment operator, ++ptr will make the pointer point to the next element in the array arr[2]. *ptr = -2 will then set the value of arr[2] to -2.
  • (*ptr)++
    • This one should be clear by now. *ptr will point us to arr[2] and thus running (*ptr)++ will increment the value of the integer that ptr is pointing to. So the value of arr[2] will  be incremented by 1 once the statement completes execution and the pointer ptr will still point to arr[2].
    • If we try to compile (*ptr)++ = 0 we will get the following compilation error:  “error C2106: ‘=’ : left operand must be l-value”.

The result would look like this:

arr[0] = 1, arr[1] = 2, arr[2] = 3, ptr = 0043FE44, *ptr = 1
arr[0] = -1, arr[1] = 2, arr[2] = 3, ptr = 0043FE48, *ptr = 2
arr[0] = -1, arr[1] = 2, arr[2] = -2, ptr = 0043FE4C, *ptr = -2
arr[0] = -1, arr[1] = 2, arr[2] = -1, ptr = 0043FE4C, *ptr = -1

Trick 2 – Array Indexing

Question

What is the result of running the following code?

void trick2()
{
    int arr[] = {1, 2, 3};

    *arr = 5;
    printf("arr[0] = %d, arr[1] = %d, arr[2] = %d\n",
           arr[0], arr[1], arr[2]);
    *(arr + 1) = 10;
    printf("arr[0] = %d, arr[1] = %d, arr[2] = %d\n",
           arr[0], arr[1], arr[2]);
    2[arr] = 15;
    printf("0[arr] = %d, 1[arr] = %d, 2[arr] = %d\n",
           0[arr], 1[arr], 2[arr]);
}

Solution

  • *arr = 5
    • An array variable can be used as a pointer, but its value can’t be changed. Think of it as a constant pointer, though they’re not quite the same. Throughout the array’s life cycle on the stack, it will always point to the first element it pointed to when it was initialized. If we try to compile arr = &i or arr = arr2 or arr = ptr, we will get a compilation error: “error C2106: ‘=’ : left operand must be l-value”.
    • So back to the statement we are trying to evaluate, this will simply set the value of the first element in the array to 5. So now arr[0] = 5.
  • *(arr + 1) = 10
    • arr is a pointer to a value of type int. Running arr + 1 would actually result in arr + 1 * sizeof(int). Assuming that arr represents address 2500 and sizeof(int) is 4, arr + 1 will actually represent address 2504 and not 2501. This is called pointer arithmetics, where the type of the object the pointer points to is taken into consideration when incrementing or decrementing the pointer.
    • *(arr + 1) is like saying arr[1] so it will let as access the second element of the array. Thus, the statement will set arr[1] to 10.
  • 2[arr] = 15
    • This is the weirdest thing I’ve learned in C, but it does make sense after all. At first you’d think this will result in a compilation error, but when compiling 2[arr], C compiler will convert it to *(2 + arr), which is the same as *(arr + 2) since addition is commutative.
    • So 2[arr] = 15 is like saying arr[2] = 15 and this the third element in the array will be set to 15.

The result would look like this:

arr[0] = 5, arr[1] = 2, arr[2] = 3
arr[0] = 5, arr[1] = 10, arr[2] = 3
0[arr] = 5, 1[arr] = 10, 2[arr] = 15

Trick 3 – Pointers to Arrays

Question

What’s the difference between str1, str2str3 and cPtr? What is the difference between sArr, sArr2DsPtr1, sPtr2 and SPtr3? What will be the result of running the code below?

void trick3()
{
    char str1[] = { 'A', 'B', 'C', 'D', 'E' };
    char str2[] = "ABCDE";
    char *str3 = "ABCDE";
    char  *cPtr = str1;

    short sArr[] = {1, 2, 3, 4, 5};
    short sArr2D[][5] = { {1, 2, 3, 4, 5},
                          {6, 7, 8, 9, 10} };
    short *sPtr1 = sArr;
    short (*sPtr2)[5] = sArr2D;
    short *sPtr3[5];

    printf("sizeof(str1) = %u\n", sizeof(str1));
    printf("sizeof(str2) = %u\n", sizeof(str2));
    printf("sizeof(str3) = %u\n", sizeof(str3));
    printf("sizeof(cPtr) = %u\n", sizeof(cPtr));
    printf("\n");

    printf("sizeof(sArr) = %u\n", sizeof(sArr));
    printf("sizeof(sPtr1) = %u\n", sizeof(sPtr1));
    printf("sizeof(sArr2D) = %u\n", sizeof(sArr2D));
    printf("sizeof(sPtr2) = %u\n", sizeof(sPtr2));
    printf("sizeof(*sPtr2) = %u\n", sizeof(*sPtr2));
    printf("sizeof(sPtr3) = %u\n", sizeof(sPtr3));
    printf("\n");

    printf("sArr2D[1][2] = %d\n", sArr2D[1][2]);
    printf("sPtr2[0][0] = %d, sPtr2[1][2] = %d\n", sPtr2[0][0], sPtr2[1][2]);
    printf("*(* (sArr2D + 1) + 2) = %d\n", *(* (sArr2D + 1) + 2));
    printf("*(*(sArr2D) + 1*5 + 2) = %d\n\n", *(*(sArr2D) + 1*5 + 2));
}

Solution

  • str1 is a char array with 5 elements: ‘A’, ‘B’, ‘C’, ‘D’, ‘E’. str2 is a char array with 6 elements ‘A’, ‘B’, ‘C’, ‘D’, ‘E’ and ”. str3 is a pointer to an array of 6 elements ‘A’, ‘B’, ‘C’, ‘D’, ‘E’ and ”. str2 and str3 seem to mean the same thing, but actually they are different. str2 is not stored on the stack (from symbol table, it directly refers to the first element in the array) while str3 is stored on the stack and contains the value of the address of the first element of the array. In other words, str3 is storing an extra pointer of size sizeof(char *), which is 4 bytes on a 32-bit system and 8 bytes on a 64-bit system. cPtr and str3 are the same in that they are pointers that point to a char array, though they are not pointing to the same array.
  • There is one additional difference between pointers and arrays. If we run sizeof on an array, we’ll get the full size of the array. However, if we run sizeof on a pointer, it will return the size of the pointer only and not the content it refers to.
    • So sizeof(str1) is 5 * sizeof(char), which is 5 * 1 = 5. sizeof(str2) is 6.
    • sizeof(str3) is the size of the pointer sizeof(char *), which is 4 bytes. sizeof(cPtr) is also 4 bytes.
  • sArr is an array of 5 short numbers. Thus, its size is 5 * sizeof(short) = 10. sPtr is a pointer that points to sArr[0]. sizeof(sPtr) is 4 bytes. sArr2D is a 2×5 2-dimensional array with size = 2 * 5 * sizeof(short) = 20. The short (*sPtr2)[5] = sArr2D will declare a pointer to an array of 2 dimensions where dimension 2 has a size of 5 then make the pointer point to the 2-dimensional array sArr2D. It does not do any allocation. So sizeof(sPtr2) is 4 bytes since it’s a pointer. The sizeof(*sPtr2) is the 5 * sizeof(short) = 10. short *sPtr3[5] creates an array of 5 pointers to short values. The array contains pointers and not short values. So sizeof(sPtr3) = 5 * sizeof(short *) = 20.
  • Multi-dimensional Array
    • sArr2D[1][2] simply tries to access the third element of the second array in the 2-dimensional array sArr2D. Think of sArr2D as an array of 2 arrays of 5 int values. So sArr2D[1][2] = 8.
    • sPtr2 is a pointer to the 2-dimensional array sArr2D and thus can be used in the same way as variable sArr2D. So sPtr2[1][2] is the same as sArr2D[1][2].
    • * (sArr2D + 1) is like sArr2D[1] which points us to the first element in the 2nd array sArr2D[1][0]. *(* (sArr2D + 1) + 2) is like *(sArr2D[1] + 2), which is like *(&sArr2D[1][0] + 2), which is like *(&sArr2D[1][1]), which is sArr2D[1][2].
    • *(sArr2D) + 1 * (column count) is the same as sArr2D[1]. So *(*(sArr2D) + 1*5 + 2) is *(&sArr2D[1][0] + 2), which is sArr2D[1][2].

The full result of the above code would look like this:

sizeof(str1) = 5
sizeof(str2) = 6
sizeof(str3) = 4
sizeof(cPtr) = 4

sizeof(sArr) = 10
sizeof(sPtr1) = 4
sizeof(sArr2D) = 20
sizeof(sPtr2) = 4
sizeof(*sPtr2) = 10
sizeof(sPtr3) = 20

sArr2D[1][2] = 8
sPtr2[0][0] = 1, sPtr2[1][2] = 8
*(* (sArr2D + 1) + 2) = 8
*(*(sArr2D) + 1*5 + 2) = 8

Source Code

Full source code for the above tricks is available on my GitHub page.